我正在使用Backbone.js构建一个应用程序.我的一些服务器端API将在特定时间后返回所有新的或更改的模型.其中一些对象对我的收藏可能是新的,所以我可以添加它们.其他可能已经存在,在这种情况下,我想更新现有的模型.所以基本上我正在寻找upsert(更新或插入)功能.
这类似于0.9.0中添加的{add:true}选项,除了我还想要更新.
有一个简单/已知的方法来做到这一点?更新代码似乎并不难,但我不想重新发明轮子.
我用通用方法解决了这种情况:
App.Utils = {
refreshCollection: function( collection, collectionJSON ){
// update/add
_( collectionJSON ).each( function( modelJSON ) {
var model = collection.get( modelJSON.id );
if( model ) {
model.set( modelJSON );
} else {
collection.add( modelJSON );
}
});
// remove
var model_ids_to_keep = _( collectionJSON ).pluck( "id" );
var model_ids = collection.pluck( "id" );
var model_ids_to_remove = _( model_ids ).difference( model_ids_to_keep )
_( model_ids_to_remove ).each( function( model_id_to_remove ){
collection.remove( model_id_to_remove );
});
},
}
Run Code Online (Sandbox Code Playgroud)
collection:是一个Backbone.CollectioncollectionJSON:是一个包含哈希样式的模型数据的数组.典型的JSON响应.我确信它可以被优化,尤其是删除部分.但由于我仍在进行测试,因此我保持这样可读性.
// code simplified and no tested
var VolatileCollection = Backbone.Collection.extend({
// url:
// model:
// so on ...
})
var PersistentCollection = Backbone.Collection.extend({
// url: not needed due this Collection is never synchronized or changed by its own
// change the VolatileCollection instead, all changes will be mirrored to this Collection
// through events
// model: the same
initialize: function( opts ){
this.volatileCollection = opts.volatileCollection;
this.volatileCollection.on( "reset", this.update, this );
this.volatileCollection.on( "change", this.update, this );
}
update: function(){
App.Utils.refreshCollection( this, this.volatileCollection.toJSON() );
}
})
var volatileCollection = new VolatileCollection();
var persistentCollection = new PersistentCollection({ volatileCollection: volatileCollection });
volatileCollection.fetch();
Run Code Online (Sandbox Code Playgroud)
注意:这个答案是为 Backbone v0.9 编写的。自那时起,Backbone v1.0 已发布,其中包含此处collection.set()描述的方法。这可能是一个更好的解决方案。
我在周末整理了自己的版本。我会把它放在这里以防其他人发现这个线程,但我仍然很高兴看到可能存在的任何其他解决方案。
我通过修改 Backbone.js 源代码来做到这一点,这不一定是个好主意,但很简单。有两个变化,首先将此函数添加到 Backbone.Collection 原型中:
//**upsert** takes models and does an update-or-insert operation on them
//So models that already exist are updated, and new models are added
upsert: function (models, options) {
var self = this;
options || (options = {});
models = _.isArray(models) ? models.slice() : [models];
var addModels = [];
_.each(models, function (newModel) {
var n = self._prepareModel(newModel, options);
var existingModel = self.get(n.id);
if (existingModel) {
existingModel.set(n, options);
} else {
addModels.push(n);
}
});
if (!_.isEmpty(addModels)) {
self.add(addModels, options);
}
}
Run Code Online (Sandbox Code Playgroud)
然后将 Backbone.Collection.fetch() 函数中的一行修改为:
collection[options.add ? 'add' : (options.upsert ? "upsert" : 'reset')](collection.parse(resp, xhr), options);
Run Code Online (Sandbox Code Playgroud)
这使您可以致电fetch({upsert:true})以获得我正在寻找的行为。
| 归档时间: |
|
| 查看次数: |
2737 次 |
| 最近记录: |