2012-12-29 109 views
9

我想觀察對象屬性的所有更改。
在下面的示例中,如果firstname或lastname發生更改,我希望由personChanged觀察者通知。
但我想通用適用於所有對象屬性(使用Ember.keys()??) 如何用更通用的東西替換'名字','姓氏'?Ember.js:觀察所有對象屬性

在我的例子:

personChangedfirstnamelastname改變被稱爲:

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

這是可能使用兩個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被稱爲任何的屬性更改。但是,由於觀察者急切地被觸發[1],所以功能personChanged應該是idempotent,其中示例中的功能不是。下一個解決方案通過讓觀察者懶惰來解決這個問題。

解決方案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實際觀測功能現在被稱爲,這可能是你正在尋找的行爲。

其他說明

這些解決方案使用ObjectProxy代替定義對象本身上的觀測,以避免設置雜散觀察員(性能如initwillDestroy,等)或explicit list of properties to observe

通過覆蓋代理上的setUnknownProperty開始觀察動態屬性,每次將密鑰添加到content時添加觀察者,可以擴展此解決方案。 willDestroy將保持不變。

參考

[1]這可能很快就改變得益於ASYN觀察員