鉴于以下模型:
(注意:这些是为了说明目的而简化)
App.CustomerOrder = DS.Model.extend({
deliveries: DS.hasMany('delivery'),
total: DS.attr('number')
});
App.Delivery = DS.Model.extend({
orderlines: DS.hasMany('orderline')
});
App.OrderLine = DS.Model.extend({
productid: DS.attr('string'),
qtyordered: DS.attr('number')
});
当应用程序首次加载时,我正在查询一个API,该API向我发送有关哪些依赖项应触发更新的信息。例如,它会发给我一些类似的东西:
CustomerOrder: ["deliveries", "deliveries.orderlines", "deliveries.orderlines.qtyordered"...]
..意味着,如果从客户添加/删除交货,或者从附加到客户订单的交货中添加/删除行,或者如果订单上的qtyordered附在客户订单上的交货中,那么API期望我将序列化CustomerOrder(以及整个关系链)并发送到一个'更新'服务(即服务器/客户/更新类型的东西),它将运行各种例程和填充数据并发送整个物体链回来了。
为了便于说明,我在这里放了一个简单的例子(我知道这很容易在客户端计算,但是还有很多其他的东西会从服务器复制代码)。因此,如果订单行上的qtyordered发生变化,我需要将customerorder实例发送到服务器,在那里它将更新我的总字段。
其中一个挑战是我不能通过使用.observes()类型的东西设置观察者函数来硬编码该依赖性列表,它必须在加载依赖性数据之后动态完成(可能使用addObserver)。另一个是观察者不会像这样深入挖掘多层。
我尝试使用混合来覆盖init函数的模型,并且正是这样做。
clientchangeset: DS.attr('raw'),
init: function() {
this._super.apply(this, arguments);
var className = this.auth.camelizedModelString(this.constructor.toString());
var watchlist = this.auth.dependencies[className] || null;
var self = this;
watchlist.forEach(function(watch) {
if(watch.hasOwnProperty('attributeName') && watch.hasOwnProperty('collectionFlag')) {
// {attributeName: attributeName, collectionFlag: collectionFlag}
if(watch['collectionFlag']) {
console.log(className+'.addObserver('+watch['attributeName']+'.@each.clientchangeset)');
self.addObserver(watch['attributeName']+'.@each.clientchangeset', null, 'updateChangelist');
} else {
console.log(className+'.addObserver('+watch['attributeName']+')');
self.addObserver(watch['attributeName'], null, 'updateChangelist');
}
}
});
},
这似乎有效,但只有一层深。为了完整性,继承了updateChangelist函数:
updateChangelist: function(src, field, value) { //jshint ignore:line
if(this.get('pauseUpdates')) {
return;
}
var className = this.auth.camelizedModelString(this.constructor.toString());
var oldclientchangeset = this.get('clientchangeset') || [];
console.log('Before: '+className+'.[clientchangeset]= '+oldclientchangeset);
oldclientchangeset.pushObject(field);
this.set('clientchangeset', oldclientchangeset);
console.log('After: '+className+'.[clientchangeset]= '+oldclientchangeset);
}
答案 0 :(得分:0)
所以一般来说,我的工作方式是按照指示创建观察者,但处理程序只是更新一个名为' _needsUpdate'在触发每个级别的关系时。 ' _needsUpdate'只是一个约会,所以当我触发时:
this.set('_needsUpdate', +new Date());
然后,当在每个级别为该级别的孩子设置观察者时,我只是设置一个观察者来看孩子。@ each._needsUpdate。