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

これを達成する方法に関する他の提案はありがたいです。たぶん、ヘルパーを1つのハンドルバーテンプレートに入れるのが最善でしょう。

編集:

上記の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

それはあなたがテンプレートを設定する方法ではありません。テンプレートは、コンパイルされたテンプレートを返すのではなく、コンパイルされたテンプレートとして機能する必要があります。コードでは、テンプレート自体を計算プロパティとして設定しようとしており、2つの可能なテンプレートを条件付きでコンパイルしています。私見では、次のように、トグルプロパティに基づいてテキストを評価する計算プロパティへのバインディングを使用してテンプレートをコンパイルする必要があります。

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 に答える