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