运行时的EmberJS动态观察程序
EmberJS dynamic observers at run-time?
给定以下模型:
(注意:为了便于说明,这些都被简化了)
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"...]
是指,如果从客户订单中添加/删除了交货,或者如果从附加到客户订单的交货中添加或删除了行,或者如果在附加到客户命令的交货的订单行上订购了qtyor,那么API希望我序列化CustomerOrder(以及整个关系链),并将其发送到"更新"服务(即服务器/客户订单/更新类型的东西),该服务将运行各种例程和填充数据,并将整个对象链发送回。
为了便于说明,我在这里放了一个简单的ordertotal示例(我意识到这在客户端很容易计算,但还有很多其他内容会与服务器的代码重复)。因此,如果订单行上的qtyorder发生更改,我需要将customerorder实例发送到服务器,它将在那里更新我的total字段。
其中一个挑战是,我不能通过用.observers()类型的东西设置observer函数来硬编码依赖列表,它必须在加载依赖数据后动态完成(可能使用addObserver)。另一个是,观察者不会像那样深入挖掘多层。
我已经尝试过在模型中使用一个mix-in来覆盖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);
}
因此,通常情况下,我实现这一点的方法是按照指示创建观察程序,但处理程序只需在触发关系时在每个级别上更新一个名为"_needsUpdate"的属性_needsUpdate只是一个日期,所以当触发时我会:
this.set('_needsUpdate', +new Date());
然后,当为该级别的孩子在每个级别设置观察者时,我只设置一个观察者来观察孩子@每个_需要更新。
- firefox插件:退出不工作的应用程序观察器
- 设置多个观察程序以触发动态事件的角度替代解决方案 - 优化的观察者模式
- 如何设置观察程序将文件复制到同一文件夹中的其他文件
- 更改可观察数组会更改自定义绑定处理程序knockoutjs的可见性
- Web Storm 9.0.3 typescript文件观察程序不工作
- angularjs如何为函数设置观察程序
- 易于实现文件观察程序
- Ember.js:如何使用选择帮助程序上的观察者来筛选内容
- 杜兰达尔多语言应用程序,页面/模块标题作为可观察的,动态更改文档.标题
- 数据绑定到可使用 javascript 在地铁风格的应用程序中观察到
- RxJS测试可观察序列,无需传递调度程序
- 创建一个依赖于可观察量“树”的 Knockout 绑定处理程序
- 运行时的EmberJS动态观察程序
- 根目录上的Gulp文件观察程序集
- 无垃圾文件观察程序
- 角度观察程序和事件侦听程序的执行顺序
- 为什么不是't我的文件观察程序正在触发
- 如何用程序更新可观察到的复杂淘汰赛
- 使用变更观察程序来观察Object.obsobe()下的本机属性
- 覆盖观察程序或检查函数内的语句