PATCH
在 Backbone.js 中保存模型属性时执行请求的正确方法是什么?
3 回答
从 Backbone.js v0.9.9 开始,您可以简单地传递{ patch: true }
给save()
.
除了James Cropchos 的回答之外,我还想添加以下内容,因为这从我身上偷走了几个小时,也许可以帮助其他人:
如果您model.save(attributesToPatchObject,{patch: true})
像 James Cropchos 回答中所述的自主干 v.0.9.9 以来可能使用的那样,您可能想知道如何确定自上次调用以来哪些属性发生了变化,model.save()
将它们作为attributesToPatchObject
第一个参数传入model.save()
(或者model.fetch()
如果你最近没有保存模型)。
Backbone 本身并没有跟踪这些属性。我认为该方法model.changedAttributes()
可能适合,但正如主干文档所说,该方法返回
仅包含自上次设置以来已更改的模型属性的哈希,如果没有,则为 false
所以这种方法不适合这种需要。经过一些研究,我发现主干本身并没有跟踪未保存的属性(我知道,如果我更仔细地阅读文档,这不是一个绝妙的发现)。
我发现backbone.trackit是一个骨干插件,它通过将方法添加unsavedAttributes()
到模型中,将所需的功能准确地添加到骨干中。Backbone.trackit 的文档谈到了这种方法:
与 Backbone 的 model.changedAttributes() 对称,但它返回自上次保存以来已更改的模型属性的哈希,如果没有则返回 false。与 changedAttributes 一样,可以传入外部属性散列,返回该散列中与模型不同的属性。
它是这样工作的:
//fetch an existing model from server
model.fetch({
success : function(model, respose, options) {
//tell backbone.trackit to track unsaved Attributes
model.startTracking();
}
});
//now some changes to the model happen
model.set("someProperty", "someValue");
/* save the model to server using the PATCH-Method
and only send the unsaved Attributes;
in this case only "someProperty" is sent
*/
model.save(model.unsavedAttributes(), {patch: true});
由于如果没有未保存的属性则unsavedAttributes()
返回false,因此您可以另外将save()
语句包装在 if 条件中,该条件检查是否unsavedAttributes()
返回false以外的内容,并且仅在需要时才执行 PATCH-Request(因为某些内容已更改)。
注意:您不必调用fetch()
使用startTracking()
,因此即使有新创建的模型(model.isNew()
在该模型上返回 true),您也可以使用此方法,如果有一个用例的话。
希望这可以节省一些人的研究时间。
您必须覆盖Backbone.sync
和扩展现有的方法映射器
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read': 'GET',
'patch': 'PATCH'
};
你必须在像这样的模型上创建自己的补丁方法
Backbone.Model.prototype.patch = function(options)
{
// some code here that checks what attributes have changed since last save
var xhr = (this.sync || Backbone.sync).call(this, 'patch', this, options);
return xhr;
}
我相信您可以进一步扩展 Backbone 以包括OPTIONS
,HEAD
如果您需要
但请注意,即使 jQuery 支持 PATCH、OPTIONS 和 HEAD 方法,您的最终用户的浏览器也可能不支持。