Views, Components, nesting and {{yield}}

In a nutshell: Within a view, all sub-views can share the same controller/model — and then the markup gets simplified, because I don’t have to pass stuff as parameters. But I can’t use this because I need component’s {{yield}}.

Long story:

Here’s my “dream markup”:

{{#x-widget title='Widget title'}}

    {{#widget-conf-box}}
        <p>
            {{! this widget's specific configuration }}

            <input type="checkbox">Option 1</input>
            <input type="checkbox">Option 2</input>
        </p>
    {{/widget-conf-box}}

    {{#widget-content}}
    <p>
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
        Aliquam magna sem, fringilla in, commodo a, rutrum ut, 
        massa. Donec id nibh eu dui auctor tempor. Morbi laoreet
        eleifend dolor.
    </p>
    {{/widget-content}}
{{/x-widget}}

This doesn’t work because of the isolation of components. They don’t see the underlying controller; all comunication between them has to be via parameters. So the markup ends up being like this:

{{#x-widget title='Widget title' color=color collapsed=collapsed editCollapsed=confBoxCollapsed}}

    {{#widget-conf-box collapsed=confBoxCollapsed}}
        <p>
            {{! this widget's specific configuration }}

            <input type="checkbox">Option 1</input>
            <input type="checkbox">Option 2</input>
        </p>
    {{/widget-conf-box}}

    {{#widget-content collapsed=collapsed}}
    <p>
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
        Aliquam magna sem, fringilla in, commodo a, rutrum ut, 
        massa. Donec id nibh eu dui auctor tempor. Morbi laoreet
        eleifend dolor.
    </p>
    {{/widget-content}}
{{/x-widget}}

The problem is, I have 10 such widgets (so far) in my application. I don’t want to repeat this parameter-passing stuff in all of them. (What if this wiring changes in the future? I would have 10+ places to change. And test).

So, I thought about using views instead of components, but view’s {{yield}} is different. It has to do with layouts. If I understood correctly, layouts are hard-coded and you can’t have more than one level of nesting (can you?).

( EDIT: This last sentence doesn’t make much sense and is probably false. I have to make some tests and improve my understanding of this. Maybe layouts can solve my problem. Still, I think the suggestions below remain valid.)

Ok. Possible solutions to this:

  1. {{view}} should have a “component-style {{yield}}” (Suggested name: {{nested}}). Or – at the cost of breaking backwards compatibility: {{view}}'s {{yield}} should have the exact same semantics of component’s, and the current {{yield}} should be renamed to {{nested}}.

  2. Add an option to component to make the isolation optional:

var WidgetConfBoxComponent = Ember.Component.extend({
    isolated: false
});

##Related topics

3 Likes

I’ve taken this approach: Ember Latest - JSFiddle - Code Playground

Let me know if I missed the question.

3 Likes

No, you didn’t. Great stuff. Thank you!