假设我有一个Backbone.Collection
有三个模型。我想替换中间的一个,将第一个和第三个模型保持在当前位置。 (假设没有comparator
。)我该怎么做?
答案 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)
尽管很久以前就提出过这个问题,但即使今天这个问题仍然存在 实际上它很容易。
请看以下示例:
var index = collection.indexOf(oldModel); //1
collection.add(newModel, {at: index, merge: true}); //2
希望它能帮助你... ... 祝你好运!