So I have the following setup.
On the main page, a list of generators is being displayed based on a list coming from a model using fixture data.
Now when one of the generator links is clicked, a new page is shown with some input fields that are dynamically generated based on that fixture data.
Until this point everything works perfectly.
Now when I change the input field's value in the generator page (after selecting one of the generators) to see the changes being updated in some sort of a preview div just below my input fields, it is easy. I can use {{generatorFields.0.value}}
to bind the first input field, .1., and so on until I bind all of them.
But as you can imagine, each generator has its own format and its own input fields, and I want to create a new .hbs file for each and every one of them and then pass that file into the generator page to show the preview.
I solved 0.1% of the problem with a partial. In the generator.hbs file I entered {{partial "generator-1"}}
and this loads my _generator-3.hbs
file that contains that {{generatorFields.0.value}}
bind, and it works. But that partial is not dynamic; I need to load a different partial each time I use a different generator. How can I achieve this?
How can I pass the partial name dynamically or load a template based on the model data that I have?
The code used so far is below:
idex.hbs looks like this:
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>Generator name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{{#each model}}
<tr>
<td>{{id}}</td>
<td>{{title}}</td>
<td>{{#linkTo 'generator' this classNames="btn btn-mini pull-right"}}Create file{{/linkTo}}</td>
</tr>
{{/each}}
</tbody>
</table>
generator.hbs
{{#each generatorFields}}
<div class="row-fluid">
<div class="span4">{{name}}</div>
<div class="span8">{{view Ember.TextField valueBinding='value' class='span12' placeholder='Type value here…'}}</div>
</div>
{{/each}}
{{partial "generator-1"}}
_generator-1.hbs
<h1>Project: {{generatorFields.0.value}}</h1>
app.js
App.Store = DS.Store.extend({
revision: 13,
adapter: 'DS.FixtureAdapter'
});
App.Router.map(function () {
this.resource('index', { path: '/' });
this.resource('generator', {path: '/generator/:generator_id'});
});
App.IndexRoute = Ember.Route.extend({
model: function () {
return App.Generator.find();
}
});
App.Generator = DS.Model.extend({
title: DS.attr('string'),
templateName: DS.attr('string'),
generatorFields: DS.attr('generatorFields')
});
// Fixture data
DS.RESTAdapter.registerTransform('generatorFields', {
serialize: function(serialized) {
return Em.none(serialized) ? {} : serialized;
},
deserialize: function(deserialized) {
return Em.none(deserialized) ? {} : deserialized;
}
});
App.Generator.FIXTURES = [{
id: 1,
title: "test 1",
generatorFields: [
{id: 1, name: "name 1", value: ""}
],
templateName: "generator-1"
}, {
id: 2,
title: "test 2",
generatorFields: [
{id: 1, name: "name 1", value: ""},
{id: 2, name: "name 2", value: ""},
],
templateName: "generator-2"
}];
You should be able to simply place your dynamic partial variable within the partial helper.
As @darshan-sawardekar pointed out if you have a generator with
templateName
ofgenerator-1
it would render the partial_generator-1
.While @Darshan's answer is simpler than the below and will work in many cases, I just ran into an issue where transitioning to a same route with a different model causes the partial to not re-render if the second model's partial name is the same as the first's (bug in ember?). Setting up a view that watches the model fixes this.
And call it with:
@KamrenZ already mentioned this but I figured I'd cite chapter and verse for those looking into this. More recent versions of Ember gracefully accept bound property names and use them in the partial helper:
http://ember-doc.com/classes/Ember.Handlebars.helpers.html#method_partial
You can create a dynamic partial helper that uses the passed in name to render with the
{{partial}}
helper.Then use this dynamic partial,
{{dynPartial}}
instead.For a generator with
templateName
ofgenerator-1
. This would render with the partial_generator-1
. Note that the name of the template's id/data-template-name must begin with an underscore.