当它是计算属性时,我在更新Ember视图上的模板属性时遇到问题。
当视图首次加载并作为属性返回时,Ember会正确编译模板,但是稍后更改依赖关系时,模板计算属性不会更新。
这是一个关于JSFiddle的例子:http://jsfiddle.net/VkJC3/
App=Em.Application.create();
App.MyView = Em.View.extend({
toggle: true
,template: function(){
if (this.get('toggle')) {
return Em.Handlebars.compile('toggle is true')
} else {
return Em.Handlebars.compile('toggle is false')
}
}.property('toggle')
});
theView= App.MyView.create();
theView.append('body');
Ember.run.later(function() {
console.log('later');
theView.set('toggle',false);
}, 2000);
对于如何实现这一点的任何其他建议表示赞赏。也许最好只将助手放入一个把手模板中。
修改
这是一个更完整的示例,显示了包含上述Ember.View的Ember.CollectionView:http://jsfiddle.net/VkJC3/6/
在Ember.run.later之后,第一个项目应该从类型1更改为类型2,并使计算的模板属性更新。
App=Em.Application.create();
App.MyView = Em.CollectionView.extend({
content: [
Em.Object.create({type: 1, data:"Maybe item type 1 is a link"})
,Em.Object.create({type: 2, data:"And item type 2 is a header"})]
,itemViewClass: Em.View.extend({
template: function(){
if (this.get('content.type')==1) {
return Em.Handlebars.compile('<a href="#">{{view.content.data}}</a>')
} else if (this.get('content.type')==2) {
return Em.Handlebars.compile('<h1>{{view.content.data}}</h1>')
}
}.property('content.type')
})
});
theView= App.MyView.create();
theView.append('body');
Ember.run.later(function() {
console.log('later');
theView.get('content')[0].set('type',2);
}, 2000);
答案 0 :(得分:3)
这不是你应该如何设置模板。模板不应返回已编译的模板,而应充当编译模板。在您的代码中,您尝试将模板本身设置为计算属性,并且您有条件地为其编译两个可能的模板。恕我直言,你应该编译一个绑定到计算属性的模板,该属性根据你的toggle属性评估文本,如下所示:
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
这只会改变需要更改的内容,因此您无需重新编译模板。
修改强>:
我对小提琴做了一些修改(你可以看到它here)。
我正在做什么,而不是直接分配template
属性,我在创建应用程序之前将模板编译到Ember.TEMPLATES
集合(我假设你会做这样的事情)无论如何prod),我正在改变你的计算属性,以根据条件(在你的情况下content.type
)返回要使用的模板的名称,并且我绑定了templateName
属性计算属性。模板更改后,您 到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...
就像我说的,这段代码可以改进......希望这有帮助