2012-12-20 18 views
1

我在更新Ember视图上的模板属性时遇到问题,它是一个计算属性。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); 
​ 

,关于如何实现这一点的任何其他的建议被理解。也许最好只把helper放到一个句柄模板中。

编辑:

这里是示出将包含在上述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); 
    ​ 

回答

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集合创建应用程序之前,(我假设你会做这样的事情在督促反正),和我” m改变你的计算属性返回模板的名称取决于条件(在你的情况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... 

就像我说的,这个代码可以改善......希望这有助于

+0

谢谢你的答复。我担心我的例子可能会使我想解决的问题过于简单化。 我想使用示例视图作为itemViewClass的Ember.CollectionView将在其内容数组中有2个或更多类型的项目。例如,包含链接,标题和分隔符的列表集合视图。然后,每个项目在itemViewClass上都有不同的模板,具体取决于该项目的内容。 – Brad

+0

我不确定我是否理解。为什么你需要将模板作为计算属性? – MilkyWayJoe

+0

我已经更新了我的示例以上下文中显示此问题。该视图被包裹在一个Ember.CollectionView – Brad