EmberJS动态观察者在运行时? [英] EmberJS dynamic observers at run-time?

查看:129
本文介绍了EmberJS动态观察者在运行时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于以下型号:

(注意:为简化目的而简化)

(note: these are simplified for illustration purposes)

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,向我发送有关哪些依赖关系应触发的信息更新。所以例如它会给我发送一些类似的东西:

When the app first loads I'm querying an API that sends me information about which dependencies should trigger an update. So for example it'll send me something like:

CustomerOrder: ["deliveries", "deliveries.orderlines", "deliveries.orderlines.qtyordered"...]

..意味着,如果从一个客户订单或如果订单从附加到客户订单的交货中添加/删除,或者如果订单上的订单在订单上附加到客户订单上,那么API期望我将序列化CustomerOrder(连同整个链关系)并发送到将运行各种例程和填充数据片段的更新服务(即服务器/客户订单/更新类型事物),并将整个对象链发回。

..means, if deliveries are added/deleted from a customerorder or if lines are added/deleted from a delivery attached to a customer order or if the qtyordered on an orderline on a delivery attached to a customer order, then what the API expects is for me to serialize CustomerOrder (along with the entire chain of relationships) and sent to an 'update' service (i.e. server/customerorder/updates type thing) that will run various routines and fill-in pieces of data and send the entire chain of objects back.

为了说明的目的,我在这里给出了一个简单的例子(我知道这很容易计算客户端,但是还有一堆其他的东西,从服务器重复代码)。所以,如果订单行上的qtyordered发生变化,我需要将customerorder实例发送到服务器,在那里它会更新我的总字段。

For illustration purposes I've put a simple example on here of an ordertotal (I realize this is easily calculated client-side but there's a bunch of other stuff that would be duplication of code from the server). So, if the qtyordered on an orderline changes, I need to send the customerorder instance to the server, where it will update my total field.

其中一个挑战是我不能通过使用.observes()类型的东西设置观察函数来硬编码依赖列表,它必须在加载相关性数据之后动态完成(大概是使用addObserver)。另一个是观察者不会像这样深入多层。

One of the challenges is that I can't hard code that dependency list by setting up observer functions with .observes() type stuff, it has to be done dynamically after that dependency data is loaded (presumably using addObserver). The other is that observers wont dig multiple layers deep like that.

我已经尝试使用混合到覆盖init函数的模型中,并且这样做。

I've tried using a mix-in to the models that overrides the init function and does exactly that.

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函数:

This appears to work, but only one layer deep. For completeness, heres the updateChangelist function:

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'只是一个日期,所以当我触发我:

So in general the way I got this to work was to create the observers as indicated, but the handlers simply update a property called '_needsUpdate' on each level of the relationships whenever they are triggered. '_needsUpdate' is just a date so when triggered I do:

this.set('_needsUpdate', +new Date());

然后,在该级别的孩子的每个级别设置观察者时,我只设置一个观察者看看孩子@ each._needsUpdate。

Then when setting up observers at each level for that level's children, I just set up a single observer to look at child.@each._needsUpdate.

这篇关于EmberJS动态观察者在运行时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆