2012-12-29 4 views
9

オブジェクトプロパティのすべての変更を確認したいと思います。
次の例では、firstnameまたはlastnameが変更された場合、personChangedオブザーバによって通知されたいと考えています。
しかし、私はすべてのオブジェクトプロパティ(Ember.keys()を使用して)に何かジェネリックを適用したいと思いますか? 'firstname'、 'lastname'をより一般的なものに置き換えるにはどうすればいいですか?私の例ではEmber.js:すべてのオブジェクトプロパティを観察する

firstnameまたはlastnameが変更されたときに

personChangedが呼び出されます。

App.MyObject: Ember.Object.create({ 
    firstname: 'first', 
    lastname: 'last', 
    personChanged: Ember.observer(function() { 
      console.log("person changed"); 
    }, 'firstname', 'lastname') 
}) 
+0

のおかげでしまうこのhttp://stackoverflow.com/questions/11623645/ember-js-observer-for-すべての値/ 11679850#11679850あなたのために働く? –

答えて

2

あなたは右のインラインオブザーバーが使用されているが、あなただけのいくつかの構文エラーが何をしています。ただし、キーワードobservesを使用する方が簡単です。だから私は少しあなたの例を微調整しました。

App.MyObject: Ember.Object.create({ 
    firstname: 'first', 
    lastname: 'last', 
    personChanged: function() { 
     //firstname or lastname changed 
    }.observes('firstname','lastname') 
}); 

注:http://emberjs.com/guides/object-model/observers/

+1

Txしかし、私の質問は、(オブザーブメソッドの属性のリストを記述することなく)すべてのオブジェクトの属性を観察する汎用的な解決策を得ることでした – fvisticot

+0

申し訳ありませんが、あなたはすべてのプロパティを配列またはオブジェクトそれを観察して手動で計算して値を取得します。 – Akash

8

これはあなたの要件に応じて、2種類でObjectProxyを使用して可能である:私は性質の前後に引用符

ソースを入れました。両方のアプローチは、オブザーバーが呼び出された回数と回数だけ異なり、両方ともEmber.keysに依存しています。

両方のソリューションのHTMLは同じです。

HTML

<script type="text/x-handlebars" data-template-name="app"> 
    Name: {{App.MyObject.firstname}} {{App.MyObject.lastname}} 

    <ul> 
    {{#each App.List}} 
     <li>{{this}}</li> 
    {{/each}} 
    </ul> 
</script> 

ソリューション1

JsFiddle:http://jsfiddle.net/2zxSq/

Javascriptを

App = Em.Application.create(); 

App.List = []; 

App.MyObject = Em.ObjectProxy.create({ 
    // Your Original object, must be defined before 'init' is called, however. 
    content: Em.Object.create({ 
     firstname: 'first', 
     lastname: 'last' 
    }), 


    // These following two functions can be abstracted out to a Mixin 
    init: function() { 
     var self = this; 
     Em.keys(this.get('content')).forEach(function (k) { 
      Em.addObserver(self.get('content'), k, self, 'personChanged') 
     }); 
    }, 

    // Manually removing the observers is necessary. 
    willDestroy: function() { 
     var self = this; 
     Em.keys(this.get('content')).forEach(function (k) { 
      Em.removeObserver(self.get('content'), k, self, 'personChanged'); 
     }); 
    }, 

    // The counter is for illustrative purpose only 
    counter: 0, 
    // This is the function which is called. 
    personChanged: function() { 
     // This function MUST be idempotent. 
     this.incrementProperty('counter'); 
     App.List.pushObject(this.get('counter')); 
     console.log('person changed'); 
    } 
}); 

App.ApplicationView = Em.View.extend({ 
    templateName: 'app' 
}); 

// Test driving the implementation. 
App.MyObject.set('firstname', 'second'); 
App.MyObject.set('lastname', 'last-but-one'); 

App.MyObject.setProperties({ 
    'firstname': 'third', 
    'lastname' : 'last-but-two' 
}); 

MyObjectを初期化しながら、が既にcontentオブジェクト上に存在するすべての特性が観察され、そして機能personChanged各時間プロパティの変更のいずれかと呼ばれています。しかし、オブザーバーは熱心に解雇されているので、関数personChangedidempotentでなければならない。次の解決策は、オブザーバーを怠惰にすることでこれを解決します。

ソリューション2

JsFiddle:http://jsfiddle.net/2zxSq/1/

Javascriptを

App.MyObject = Em.ObjectProxy.create({ 
    content: Em.Object.create({ 
     firstname: 'first', 
     lastname: 'last' 
    }), 


    init: function() { 
     var self = this; 
     Em.keys(this.get('content')).forEach(function (k) { 
      Em.addObserver(self, k, self, 'personChanged') 
     }); 
    }, 

    willDestroy: function() { 
     var self = this; 
     Em.keys(this.get('content')).forEach(function (k) { 
      Em.removeObserver(self, k, self, 'personChanged'); 
     }); 
    }, 

    // Changes from here 
    counter: 0, 
    _personChanged: function() { 
     this.incrementProperty('counter'); 
     App.List.pushObject(this.get('counter')); 
     console.log('person changed'); 
    }, 

    // The Actual function is called via Em.run.once 
    personChanged: function() { 
     Em.run.once(this, '_personChanged'); 
    } 
}); 

ここでの唯一の変化は、実際の観測機能は、現在、唯一the end of the Ember Run loopでいるかもしれないと呼ばれているということですあなたが探している行動です。

他ノート

これらの溶液の代わりに偽の観察者(等initwillDestroy、などの特性に)またはexplicit list of properties to observe設定避けるために、オブジェクト自体にオブザーバを定義するObjectProxyを使用します。

このソリューションは、キーがcontentに追加されるたびにオブザーバを追加するために、プロキシのsetUnknownPropertyをオーバーライドして動的プロパティの監視を開始するように拡張できます。 willDestroyは同じままです。

リファレンス

[1]これはすぐに変更される可能性がありますASYNオブザーバー

関連する問題