Multiple yield in a component

In the current component implementation, you can only have single {{yield}}. It is fine most of the time, but sometimes it would be nice to have a multiple named yields (think header, body, footer kind of thing).

With a single yield, you sometime have to expose some internal parts of your component. If you have a simple dialog with a header and boby that need to be wrapped too:

{{#dialog}}
  {{#dialog-header}} header {{/dialog-header}}
  {{#dialog-body}} body {{/dialog-body}}
{{/dialog}}

This leads to 2 problems:

  1. you expose the internals (what if in the future you do not require header to be wrapped?)
  2. you force the user to know they have to use wrappers for the header and body.

To be able to handle more than 1 yield, I would give the component special attributes in the form of template names that will fill in the {{yield name}}.

I can already do this using {{partial}}, but it seems {{yield}} would be more inline with the current implementation.

Any thoughts?

1 Like

I totally agree, this was last discussed here but I haven’t seen much motion on it.

Example of it working: Ember Latest - JSFiddle - Code Playground (not my code, @machty’s example just had outdated libs)

Not working on current ember-latest, default sub-component templates are used instead of the redefined ones…

It appears that in ember 1.9 whole template for the component is rendered first, and only then {{yield}} is called, inserting yielded template to the appropriate position. Thus templates for the {{content-for}} regions are defined too late in the process for this approach to work.

I fixed it in 1.9 by introducing new {{eval}} helper which evaluates child template immediately. This will however not work for 1.10 with HTMLbars templates - {{eval}} helper will have to be updated accordingly.

Updated example: JSFiddle

Ember 1.10 opens up some possibilities.

I’ve probably got some reading to do, but what’s the latest on this? I’ve got an expanding box component that hides all content. In some situations I’d really like some dynamic content that stays visible all the time. Multiple yields would be the easiest way to do this…