在ember中设置嵌套数组上的属性observable时,不会通知我的属性。
size: function(){
var result = "no size";
this.get('data.properties').forEach(function (g) {
if (g.group == "style") {
g.items.forEach(function (p) {
if (p.id == 'size') result = p.computedValue();
});
}
});
console.log(result);
return result;
}.property('data.properties.@each.items.@each.value')
在此SO接受的答案中:https://stackoverflow.com/a/9381152/2068563 它说这应该有效。
但对我来说,这个预言只在init计算。 这是小提琴:http://jsfiddle.net/jmorvan/eVWfj/
有什么想法吗?
答案 0 :(得分:1)
好的,解决方法是将observable更新的计算属性链接到这样的事件:
App.groupObj = Ember.Object.extend({
group: "style",
name: "Style",
_changed: 0,
changed: function (key, value) {
if (value) {
this.set('_changed', value);
}
return this.get('_changed');
}.property(),
itemChanged: function () {
this.set('changed', +new Date());
console.log('item changed!');
}.observes('items.@each.val'),
items: []
});
App.itemObj = Ember.Object.extend({
_val: 6,
id: null,
name: null,
group: null,
fieldType: null,
val: function (key, value) {
if (value) {
this.set('_val', value);
}
return this.get('_val');
}.property(),
computedValue: function () {
return this.val;
}
});
基本上,grouo对象侦听项目的val属性上的任何操作并更新自己更改的属性。我这样做可以做到:
size: function(){
var result = "no size";
this.get('data.properties').forEach(function (g) {
if (g.group == "style") {
g.items.forEach(function (p) {
if (p.id == 'size') result = p.computedValue();
});
}
});
console.log(result);
return result;
}.property('data.properties.@each.changed')
我想我的第一个miastake是认为ember神奇地在我的嵌套对象上拾取更改。
我还认为链接计算属性会起作用,这显然没有! (为什么?)
更新的小提琴:http://jsfiddle.net/jmorvan/LEyCD/
由于在每个对象上实现的时间很长,因此我使用基于选择器的observable创建了自己的对象。
App.changeAwareArray = Ember.ArrayProxy.extend({
init: function () {
this.set('content', []);
this._super();
if (!this.get('changeSelector')) this.set('changeSelector', '_changed');
this.addObserver('content.@each.' + this.get('changeSelector'), this.handleChange);
},
_changed: null,
handleChange: function () {
this.set('_changed', +new Date());
}
});
App.changeAwareObject = Ember.Object.extend({
init: function () {
this._super();
if (!this.get('changeSelector')) this.set('changeSelector', '_changed');
this.addObserver(this.get('changeSelector'), this.handleChange);
},
_changed: null,
changed: function (key, value) {
if (value) {
this.set('_changed', value);
}
return this.get('_changed');
}.property(),
handleChange: function () {
this.set('_changed', +new Date());
}
});
现在你可以将它们链接起来观察它们:
App.groupObj = App.changeAwareObject.extend({
changeSelector:'items._changed',
group: "style",
name: "Style",
items: App.changeAwareArray.create()
});
App.itemObj = Ember.Object.extend({
_val: 6,
_changed: null,
id: null,
name: null,
group: null,
fieldType: null,
val: function (key, value) {
if (value) {
this.set('_val', value);
this.set('_changed', +new Date());
}
return this.get('_val');
}.property(),
computedValue: function () {
return this.val;
}
});
获取视图/控制器中的数据:
App.IndexView = Ember.View.extend({
init: function () {
this._super();
//populate the Array
this.data.properties.pushObject(createData());
},
elementId: "test",
size: function () {
var result = "no size";
this.get('data.properties').forEach(function (g) {
if (g.group == "style") {
g.items.forEach(function (p) {
if (p.id == 'size') result = p.computedValue();
});
}
});
return result;
}.property('data.properties._changed'),
offset: function () {
var result = "no offset";
this.get('data.properties').forEach(function (g) {
if (g.group == "style") {
g.items.forEach(function (p) {
if (p.id == 'offset') result = p.computedValue();
});
}
});
return result;
}.property('data.properties._changed'),
data:{
name: "base",
properties: App.changeAwareArray.create()
}
});
你可以在这里找到一个工作小提琴:http://jsfiddle.net/jmorvan/VRVac/