1

当 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);
​

任何其他关于如何实现这一点的建议表示赞赏。也许最好只将 if 助手放入一个车把模板中。

编辑:

这是一个更完整的示例,显示将包含上述 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);
    ​
4

1 回答 1

3

这不是您应该设置模板的方式。模板不应返回已编译的模板,而应充当已编译的模板。在您的代码中,您尝试将模板本身设置为计算属性,并且您正在有条件地编译两个可能的模板。恕我直言,您应该编译一个绑定到计算属性的模板,该属性根据您的切换属性评估文本,如下所示:

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);

在这里看小提琴

这只会更改需要更改的内容,因此您不必重新编译模板。

编辑

我对小提琴做了一些修改(你可以在这里看到)。

我在做什么,而不是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... 

就像我说的,这段代码可以改进......希望这会有所帮助

于 2012-12-20T20:35:01.353 回答