Ember.js:观察所有对象属性

Ember.js:观察所有对象属性,ember.js,Ember.js,我希望观察对象属性的所有更改。 在下面的示例中,如果firstname或lastname发生更改,我希望personChanged观察员通知我。 但是我想在所有对象属性上应用一些通用的东西(使用Ember.keys()??) 如何将“firstname”、“lastname”替换为更通用的名称 在我的例子中: 更改firstname或lastname时调用personChanged: App.MyObject: Ember.Object.create({ firstname: 'firs

我希望观察对象属性的所有更改。
在下面的示例中,如果firstname或lastname发生更改,我希望personChanged观察员通知我。
但是我想在所有对象属性上应用一些通用的东西(使用Ember.keys()??) 如何将“firstname”、“lastname”替换为更通用的名称

在我的例子中:

更改
firstname
lastname
时调用
personChanged

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

您现在使用的是内联观察器,但您只是有一些语法错误。但是,使用关键字
更简单。因此,我在下面稍微调整了一下您的示例

App.MyObject: Ember.Object.create({
    firstname: 'first',
    lastname: 'last',
    personChanged: function() {
        //firstname or lastname changed
    }.observes('firstname','lastname')
});
注意:我在属性周围加了引号


来源:

根据您的需求,可以使用两种风格的
ObjectProxy
。这两种方法仅在何时和调用观察者的次数上有所不同,并且都依赖于
Ember.keys

两种解决方案的HTML是相同的

HTML

初始化
MyObject
时,会观察
内容
对象上已经存在的所有属性,并且每次属性更改时都会调用函数
personChanged
。然而,由于观察者被急切地解雇[1],函数
personChanged
应该是,而示例中的函数不是。下一个解决方案通过使观察者懒惰来解决这个问题

解决方案2

JsFiddle:

Javascript

App.MyObject=Em.ObjectProxy.create({
内容:Em.Object.create({
名字:'第一',
姓氏:“last”
}),
init:函数(){
var self=这个;
Em.keys(this.get('content')).forEach(函数(k){
Em.addObserver(self,k,self,'personChanged')
});
},
willDestroy:函数(){
var self=这个;
Em.keys(this.get('content')).forEach(函数(k){
Em.removeObserver(self,k,self,'personChanged');
});
},
//这里的变化
柜台:0,,
_人员变更:功能(){
此.incrementProperty(“计数器”);
App.List.pushObject(this.get('counter');
console.log(“人员变更”);
},
//实际函数通过Em.run.once调用
人员变更:功能(){
跑一次(这个“人变了”);
}
});
这里唯一的变化是,实际的观察者函数现在只在调用,这可能是您正在寻找的行为

其他注释

这些解决方案使用
ObjectProxy
,而不是在对象本身上定义观察者,以避免设置虚假的观察者(在
init
willDestroy
等属性上)或错误

通过覆盖代理上的
setUnknownProperty
,可以扩展此解决方案,以便在每次向
内容添加键时添加观察者,从而开始观察动态属性。
将销毁
将保持不变

参考


[1] 由于Asyn Observators

Tx,这一点可能很快就会改变,但我的问题是获得一个通用解决方案来观察所有对象属性(无需在观察方法中写入属性列表)很抱歉,除非您将所有属性存储在一个数组或一个对象中,并观察这些属性,然后执行一些手动计算以检索值,否则无法执行此操作。这对您有用吗?
<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>
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'
});