如何替换Backbone.Collection中的模型?

时间:2011-06-06 18:25:47

标签: backbone.js

假设我有一个Backbone.Collection有三个模型。我想替换中间的一个,将第一个和第三个模型保持在当前位置。 (假设没有comparator。)我该怎么做?

5 个答案:

答案 0 :(得分:18)

这是一个很好的问题,今天仍然有用,所以值得回答。

当您提出问题时,我的答案中使用的功能可能不存在,但现在执行此操作非常简单。

无论如何,我们假设您的集合名为myCollection,并且已经存储了3个模型。让我们假设您有一个名为newModel的新模型,您希望用它来替换集合中现有的中间模型。要替换中间模型,保持第一个和第三个模型不变,您可以这样做:

myCollection.remove(myCollection.at(1));

myCollection.add(newModel, {at: 1});

这将完全符合您的要求,并为已删除的模型提升remove事件,并为替换提升add事件,这也是您想要的。

答案 1 :(得分:6)

Backbone中内置了一个处理此问题的简单机制

myCollection.add(newModel, {merge: true});

答案 2 :(得分:2)

您可以在主干集合中引入一个类似于以下内容的replaceAt函数:

   replaceAt : function(model, options, replaceIndex) {
      this._replaceAt(model, options, replaceIndex);
      return this;
    },

   _replaceAt : function(model, options, replaceIndex) {

      options || (options = {});
      if (!(model instanceof Backbone.Model)) {
        model = new this.model(model, {collection: this});
      }
      var already = this.getByCid(model);
      if (already) throw new Error(["Can't add the same model to a set twice", already.id]);
      this._byId[model.id] = model;
      this._byCid[model.cid] = model;
      model.collection = this;
      replacedModel = this.at(replaceIndex)
      this.models.splice(replaceIndex, 1, model);
      this._cleanModel(replacedModel, options);
      model.bind('all', this._boundOnModelEvent);
      if (!options.silent) model.trigger('add', model, this, options);
      return model;
    },

    _cleanModel : function (model, options) {
      if(!model) return null;
      delete this._byId[model.id];
      delete this._byCid[model.cid];
      delete model.collection;
      if(!options.silent) model.trigger('remove', model, this, options);
      model.unbind('all', this._boundOnModelEvent);
      return model;
    },

它基于_add和_remove方法。它应该触发您正在寻找的相应事件,但我没有测试它。我测试过它会在适当的地方替换集合中的元素。

(使用骨干.3.3)

答案 3 :(得分:0)

一种方法是直接修改collection.models数组,然后调用

collection.refresh(collection.models)

但是,这将调用列出每个模型的add事件。理想情况下,我想为已删除的模型调用remove事件,为新模型调用add事件。我不确定是否可以不使用comparator并在我的模型上添加索引......

答案 4 :(得分:0)

尽管很久以前就提出过这个问题,但即使今天这个问题仍然存在 实际上它很容易。

  1. 我们需要在集合中获取旧的模型索引。
  2. 然后将新的一个添加到相同索引位置的集合中并合并
  3. 请看以下示例:

     var index = collection.indexOf(oldModel); //1  
     collection.add(newModel, {at: index, merge: true}); //2
    

    希望它能帮助你... ... 祝你好运!