Backbone.js set导致已经在集合中的模型再次“初始化”

时间:2013-06-26 14:10:52

标签: javascript html backbone.js

目前我有一个服务器调用,它返回两个对象和一个用于设置集合的对象。 (我每10秒轮询一次,很快将使用socket.io)。

我注意到每次使用set collection with object时都会调用我的模型初始化函数。我认为这个设置是智能的,只添加/更改了attr或删除了模型,对于那些未更改的设备只是什么也没做。

// All Orders Collection
var AllOrders = Backbone.Collection.extend({
    model: Order,
    url: '/venues/orders'
 });


 var Order = Backbone.DeepModel.extend({
     idAttribute: 'orderid',
     url: '/venues/orders',


    initialize : function(){
        // this is called everytime i use set even if model is in collection
        // do stuff
    }
 })


 *****************
 app.allOrders.set( app.getOrders.get('orders') );

2 个答案:

答案 0 :(得分:2)

如果你看一下主干来源,

将模型合并到集合中时,在合并之前调用_prepareModel方法,从传入的属性创建新模型。

这是set code

 if (!(model = this._prepareModel(attrs = models[i], options))) continue;

    // If a duplicate is found, prevent it from being added and
    // optionally merge it into the existing model.
    if (existing = this.get(model)) {
      if (remove) modelMap[existing.cid] = true;
      if (merge) {
        attrs = attrs === model ? model.attributes : options._attrs;
        existing.set(attrs, options);
        if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
      }

所以会发生什么,

  • 根据传入的属性
  • 创建新模型
  • 查询集合,查找与新ID相同的现有模型。
  • 如果合并选项为true,则会将新属性推送到现有模型。

答案 1 :(得分:0)

这取决于您编写客户端和服务的方式。默认情况下,GET /场地/订单返回整个订单列表。如果您只想获取更改,则必须为订单集合编写自定义同步,以保留当前订单,并仅从服务器获取更改(例如,您发送当前ID,或者您发送最后一次调用的时间戳) )。顺便说一句。初始化将由每个获取的模型调用,因为它们是从json创建的,而collection.set无法将json对象与骨干模型进行比较,它只能将骨干模型与骨干模型进行比较。

可能的解决方案:

  1. 覆盖设置以将json与骨干模型进行比较。
  2. 覆盖您的 app.getOrders.get('orders')&服务器端代码仅下拉更改,或手动从已拉出的json中删除已存在的对象。
  3. 将代码从初始化移动到另一个位置,例如移动到collection.add事件处理程序。