假设我有一个Collection,并且我对其许多模型进行了更改。使用单个HTTP请求保存所有更改的最佳方法是什么?
答案 0 :(得分:24)
通常,REST后端处理单个实例的创建/更新。您需要更改它以接受对象数组。
也就是说,在客户端,你需要直接进入Backbone.sync函数
Backbone.sync = function(method, model, options)
在这种情况下,您的模型应该是一个模型数组。该方法应该是“创建”或“保存”,并且选项采用与jQuery ajax调用相同类型的选项(错误,成功等)
答案 1 :(得分:12)
我将在这里做错误的事情并引用维基百科关于proper RESTful practices: PUT 到example.com/resources
应该用另一个集合替换整个集合。基于此,当我们不得不支持同时编辑多个项目时,我们写了这份合同。
{"resources": [{resource1},{resource2}]}
{"resources": [{"id":1,...},{"id":2,...}]}
我们在Rails中写了服务器的一半合同,但这是客户端的一半(在CoffeeScript中,抱歉!):
class ChildElementCollection extends Backbone.Collection
initialize: ->
@bind 'add', (model) -> model.set('parent_id', @parent.id)
url: -> "#{@parent.url()}/resources" # let's say that @parent.url() == '/parent/1'
save: ->
response = Backbone.sync('update', @, url: @url(), contentType: 'application/json', data: JSON.stringify(children: @toJSON()))
response.done (models) => @reset models.resources
我认为这是 lot 更容易实现,然后重写Backbone.sync。关于代码的一个注释,我们的集合总是子对象,这可以解释为什么每当对象被添加到集合时代码设置“parent_id”,以及URL的根是父对象的URL。如果您要修改根级别集合,则只需删除@parent
业务。
答案 2 :(得分:6)
您应该扩展Backbone.Collection
,为其提供save()
方法,以检查其每个模型hasChanged()
。
然后它应该调用Backbone.sync
,您可能需要将其扩展到自定义同步功能。如果您使用自定义Backbone.sync
功能,请务必在您的收藏中进行设置。
var CollectionSync = function(method, model, [options]) {
// do similar things to Backbone.sync
}
var MyCollection = Backbone.Collection.extend({
sync: CollectionSync,
model: MyModel,
getChanged: function() {
// return a list of models that have changed by checking hasChanged()
},
save: function(attributes, options) {
// do similar things as Model.save
}
});
另一种方法(使用模型来表示集合)在这里:"How" to save an entire collection in Backbone.js - Backbone.sync or jQuery.ajax?
答案 3 :(得分:0)
此代码向集合原型添加了一个新方法,只是为了调用那些已更改的模型的save方法。它对我有用:
Backbone.Collection.prototype.saveAll = function(options) {
return $.when.apply($, _.map(this.models, function(m) {
return m.hasChanged() ? m.save(null, options).then(_.identity) : m;
}));
};
要点链接:https://gist.github.com/julianitor/701c677279bac1529b88