EmberJS multiple yield helper
Asked Answered
C

3

8

I have a custom view that I've created in Ember. I really love the {{yield}} helper to allow me to control the 'bread' of the sandwich. However, what I'd like to do now, is create a 'double decker' sandwich, and have a view with more than 1 yield in it, or at the very least be able to parameterize which template to use in the 2nd yield.

so for example:

layout.hbs

<div>
    <div class="header">Header Content</div>
    <div class="tab1">
        Tab 1 Controls.
        <input type="text" id="common1" />
        {{yield}}
    </div>
    <div class="tab2">
        Tab 2 Controls.
        <input type="text" id="common2" />
        {{yield second-template}} or {{template second-template}}
    </div>
</div>

app.js

App.MyDoubleDeckerView = Ember.View.extend({
    layoutName:"layout',
    templateName:"defaultTemplate", 
    "second-template":"defaultSecond"
});

App.MyExtendedDoubleDecker = App.MyDoubleDeckerView({
    templateName:"myTemplate", 
    "second-template":"mySecondTemplate"
});

is there any way of doing something like this? What I love about the views in ember is the ability to centralize & extend views which allows me to keep the things that are common among all the views in one place...

Cougar answered 22/7, 2013 at 18:38 Comment(7)
Why not to use ContainerView instead?Cadman
From what I can tell you can't use ContainerView declaratively in the templates... is that right?Cougar
I found a work around using some jQuery. I define my stuff for the 2nd tab in a div, then use appendTo to move it over to the 2nd tab in the didInsertElement object... not pretty but it worksCougar
ContainerView is really an array of views and you can add views to it in imperative way if required. Check out emberjs.com/api/classes/… "Adding a view" section. The regular pushObject is appending new views. In your case you would like to nest a container view in another view to acts as its template.Cadman
I answered a similar problem here. Let me know if its helpful: #20842447Taciturn
@ben have you found an answer for this? If so, I encourage you self-answer and to close this issue :)Insatiable
@Cougar I wonder if you would mind taking a look at this discussion over here: discuss.emberjs.com/t/… because it might be what you're looking for? Alternatively, I wonder if multiple outlets might be what you're after? #14532456Insatiable
D
1

As of Ember 3.25 you can use so called "named blocks" (see the Passing multiple blocks subsection of https://api.emberjs.com/ember/release/modules/@glimmer%2Fcomponent).

Example component:

<h1>{{yield to="title"}}</h1>
{{yield}}

and then use it like this:

<PersonProfile @person={{this.currentUser}}>
  <:title>{{this.currentUser.name}}</:title>
  <:default>{{this.currentUser.siganture}}</:default>
</PersonProfile>
Decarburize answered 16/3, 2021 at 7:42 Comment(0)
I
0

I think you should use named outlets for this

http://emberjs.com/guides/routing/rendering-a-template/

Insatiable answered 4/5, 2014 at 4:31 Comment(0)
A
0

Something like this should work:

layout.hbs

<div>
    <div class="header">Header Content</div>
    <div class="tab1">
        Tab 1 Controls.
        <input type="text" id="common1" />
        {{yield}}
    </div>
    <div class="tab2">
        Tab 2 Controls.
        <input type="text" id="common2" />
        {{view "view.secondView"}}
    </div>
</div>

app.js

App.MyDoubleDeckerView = Ember.View.extend({
    layoutName:"layout',
    templateName:"defaultTemplate", 
    secondView: Ember.view.extend({
        templateName: "defaultSecond"
    })
});

App.MyExtendedDoubleDecker = App.MyDoubleDeckerView({
    templateName:"myTemplate", 
    secondView: Ember.view.extend({
        templateName: "mySecondTemplate"
    });
});

In other words, invoke a view given by view.secondView from within your template. Then, set the secondView property in your class or subclass.

You could add a bit of syntactic sugar with

App.viewForTemplateName = function(templateName) {
    return Ember.View.extend({
        templateName: templateName
    });
};

Then, in your view definitions above, do

secondView: App.viewForTemplateName('mySecondTemplate')
Aldose answered 4/5, 2014 at 4:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.