Reputation: 536
Given that I have this code:
Ember.App.View = Ember.View.extend({
templateName: "templateA"
});
Ember.App.View = Ember.View.extend({
templateName: "templateB"
});
Ember.App.ViewC = Ember.CollectionView.extend({
itemViewClass: "Ember.View",
contentBinding: "SomeController"
});
Is there a way to add views with different templates to CollectionView?
Upvotes: 2
Views: 2788
Reputation: 1657
In case you also need mutable view class you can use following tooling:
listview.hbs
{{each item in list itemViewClass=view.Item}}
listview.js
import Ember from 'ember';
import { mutableView } from 'utils/mutable-view';
export default Ember.View.extend({
Item: mutableView('content.type', function (type, container) {
if (type === 'type_a') {
return container.lookupFactory('view:item-a-view');
}
if (type === 'type_b') {
return container.lookupFactory('view:item-b-view');
}
}),
});
and finally the utility method mutableView of mutable-view.js
import Ember from 'ember';
var mutableViewTemplate = Ember.Handlebars.compile('{{view view.DynamicView content=view.content}}');
export var mutableView = function(observes, viewSelector) {
return Ember.View.extend({
template: mutableViewTemplate,
__dynamicViewCache: {},
DynamicView: Ember.computed(observes, function () {
var view;
var cache = this.get('__dynamicViewCache');
var modificator = this.get(observes);
view = cache[modificator];
if (view) {
return view;
}
view = viewSelector(modificator, this.get('container'));
if (view) {
cache[modificator] = view;
return view;
}
throw new Error(`Cannot determine view class for '${modificator}' of '${observes} '`);
})
});
};
Upvotes: 0
Reputation: 16163
You can make the templateName
of the itemViewClass
a computed property, see http://jsfiddle.net/pangratz666/vGHcD/:
App.MyView = Ember.View.extend({
templateName: function() {
var templateName = Ember.getPath(this, 'content.label');
// return default template if there is no such template
return (!Ember.TEMPLATES[templateName]) ? 'default' : templateName;
}.property('content.label').cacheable(),
// rerender the view if the template name changes
_templateNameChanged: function() {
this.rerender();
}.observes('templateName')
});
App.CollectionView = Ember.CollectionView.extend({
itemViewClass: 'App.MyView'
});
Also take a look at the related question: Select view template by model type/object value using Ember.js
Upvotes: 6
Reputation: 16163
Another solution is to use ghempton/ember-layout, see http://jsfiddle.net/pangratz666/XhfYy/:
App.ViewA = Ember.View.extend({
templateName: "templateA"
});
App.ViewB = Ember.View.extend({
templateName: "templateB"
});
App.ItemView = Ember.View.extend({
template: Ember.Handlebars.compile('{{dynamicView content}}')
});
App.CollectionView = Ember.CollectionView.extend({
itemViewClass: 'App.ItemView'
});
App.controller = Ember.ArrayProxy.create({
content: [App.ViewA.create(), App.ViewB.create()]
});
Upvotes: 0