我已经结束了用一些方法来处理这个问题,以增强Backbone.Collection。
的saveChangeMethod创建要传递给Backbone.sync一个假人模型。模型中所有主干的同步方法需求都是它的url属性和JSON方法,所以我们可以很容易地将其敲除。
在内部,模型的toJSON方法只返回其属性的副本(要发送到服务器),所以我们可以愉快地使用刚刚返回模型数组的toJSON方法。 Backbone.sync对此进行了字符串处理,这使我们只知道属性数据。
成功时,saveChanged触发关闭事件的集合进行一次处理。使用了一些代码,它可以为每个批次模型中已更改的每个属性触发特定事件一次。
Backbone.Collection.prototype.saveChanged = function() {
var me = this,
changed = me.getChanged(),
dummy = {
url: this.url,
toJSON: function() {
return changed.models;
}
},
options = {
success: function (model, resp, xhr) {
for (var i = 0; i < changed.models.length; i++) {
changed.models[i].chnageSilently();
}
for (var attr in changed.attributes) {
me.trigger("batchchange:" + attr);
}
me.trigger("batchsync", changed);
}
};
return Backbone.sync("update", dummy, options);
}
然后,我们只需要对集合的getChanged()方法。这将返回一个对象2周的特性,改变后的模型的阵列以及哪些属性已改变的对象检举:
Backbone.Collection.prototype.getChanged = function() {
var models = [],
changedAttributes = {};
for (var i = 0; i < this.models.length; i++) {
if (this.models[i].hasChanged()) {
_.extend(changedAttributes, this.models[i].changedAttributes());
models.push(this.models[i]);
}
}
return models.length ? {models: models, attributes: changedAttributes} : null;
}
虽然这是预期的用途骨架“改变的模型”范式,整点的轻微滥用的配料是,当模型改变时,我们不希望发生任何事情(即任何事件发生)。
因此,我们必须将{silent:true}传递给模型的set()方法,所以使用backbone的hasChanged()来标记等待保存的模型是有意义的。当然,如果你为了其他目的而默默地改变模型,这会有问题 - collection.saveChanged()也会保存它们,所以值得考虑设置一个替代标志。在任何情况下,如果我们这样做,当保存时,我们需要确保骨干现在认为模型没有改变(不触发它们的改变事件),所以我们需要手动操纵模型,就好像它没有改变。该saveChanged()在我们改变模型方法进行迭代,并呼吁模式,这基本上是骨干model.change()方法不触发这个changeSilently()方法:
Backbone.Model.prototype.changeSilently = function() {
var options = {},
changing = this._changing;
this._changing = true;
for (var attr in this._silent) this._pending[attr] = true;
this._silent = {};
if (changing) return this;
while (!_.isEmpty(this._pending)) {
this._pending = {};
for (var attr in this.changed) {
if (this._pending[attr] || this._silent[attr]) continue;
delete this.changed[attr];
}
this._previousAttributes = _.clone(this.attributes);
}
this._changing = false;
return this;
}
用法:
model1.set({key: value}, {silent: true});
model2.set({key: value}, {silent: true});
model3.set({key: value}, {silent: true});
collection.saveChanged();
RE。 RESTfulness ..对集合的端点执行PUT以更改它的某些记录是不正确的。从技术上讲,PUT应该取代整个集合,但直到我的应用程序实际上需要替换整个集合时,我很乐意采取实用的方法。
相关:http://stackoverflow.com/questions/11819662/why-does-backbone-not-have-a-save-put-post-method-for-its-collections-is-i/11819965#11819965 | http://stackoverflow.com/questions/11042292/extend-backbone-sync-to-batch-sync | http://stackoverflow.com/questions/511281/patterns-for-handling-batch-operations-in-rest-web-services | http://stackoverflow.com/questions/8529919/how-to-update-a-set-of-records-using-backbone-js-rails – fguillen