这不是您应该设置模板的方式。该模板不应返回已编译的模板,而应充当已编译的模板。在您的代码中,您尝试将模板本身设置为计算属性,并且有条件地向其编译两个可能的模板。恕我直言,您应该编译一个模板,该模板绑定到一个计算属性,该属性根据您的切换属性评估文本,如下所示:
App = Em.Application.create();
App.MyView = Em.View.extend({
template: Em.Handlebars.compile('toggle is {{toggleState}}'),
toggle: true,
toggleState: function(){
if (this.get('toggle')) {
return 'set to \'true\'';
} else {
return 'set to \'false\'';
}
}.property('toggle')
});
theView = App.MyView.create();
theView.append('body');
Ember.run.later(function() {
console.log('later');
theView.set('toggle',false);
}, 2000);
参见小提琴here http://jsfiddle.net/VkJC3/4/
这只会更改需要更改的内容,因此您不必重新编译模板。
EDIT:
我对小提琴做了一些修改(你可以看到它here http://jsfiddle.net/VkJC3/23/).
我正在做什么,而不是分配template
直接属性,我将模板编译为Ember.TEMPLATES
在创建应用程序之前收集(我假设您无论如何都会在产品中执行类似的操作),并且我正在更改您的计算属性以根据条件返回要使用的模板的名称(在您的情况下)content.type
),并且我正在绑定templateName
计算属性的属性。模板更改后,您have to rerender
你的观点。代码可以改进,但我将其粘贴到此处来演示解决方案:
(function() {
Em.TEMPLATES["one"] = Em.Handlebars.compile('<a href="#">{{view.content.data}}</a>');
Em.TEMPLATES["two"] = Em.Handlebars.compile('<h1>{{view.content.data}}</h1>');
})();
App = Em.Application.create();
App.MyView = Em.CollectionView.extend({
content: [
Em.Object.create({type: 1, data:"Item type 1 is a link"}),
Em.Object.create({type: 2, data:"Item type 2 is a header"})
],
itemViewClass: Em.View.extend({
templateNameBinding: 'currentTypeName',
currentTypeName: function() {
if (this.get('content.type') == 1) {
return "one";
} else if (this.get('content.type') == 2) {
return "two";
}
}.property('content.type'),
templateNameObserver: function() {
this.rerender();
}.observes('templateName')
})
});
// ... rest of the code...
就像我说的,这段代码可以改进......希望这有帮助