保存模型时如何强制执行 POST 请求?
How to force a POST request when saving a model?
我需要制作一个 POST 到服务器端 API。我必须将 id
密钥发送到服务器的请求正文中。
我使用 Backbone 模型。但是当我这样做时:
myModel.set("id", somevalue)
myModel.save()
触发的网络请求是:URL/someValue [PUT]
Backbones 不执行 POST 而是执行 PUT 并将 id 附加到 url.
所以我只想在 Backbone 不注意的情况下将 id
密钥传递给服务器。
Backbone is pre-configured to sync with a RESTful API.
[...]
The default sync
handler maps CRUD to REST like so:
- create →
POST /collection
- read →
GET /collection[/id]
- update →
PUT /collection/id
- patch →
PATCH /collection/id
- delete →
DELETE /collection/id
新条目没有 ID,因此如果您在保存之前为模型提供 ID,Backbone 默认为 PUT 请求,因为它认为您要保存现有条目。
如何使用 id 发出 POST 请求?
选择以下解决方案之一。
坚持RESTfulAPI
这一个是显而易见的。可以的话,坚持标准。
更改 API 以处理 PUT/PATCH 请求并仅在创建时使用 POST。使 API 端点从 URL.
获取 ID
传递type
选项1
简单且非常适合一次性情况。
传递给 save
(或 fetch
)的每个选项都会覆盖 sync
函数默认定义的选项并传递给 jQuery.ajax
function.
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
var url = model.url(); // get the url before setting the `id`
model.save({
id: somevalue
}, {
url: url, // fix the url
type: 'POST' // choose the HTTP verb
});
修复模型使用的url很简单,你也有一些选择:
- 传递
url
选项(如上)
- 覆盖模型的
url
function
重写 url
函数 (source) 适用于每次调用都应使用特定 url 而无需附加默认值 id
的情况。
var MyModel = Backbone.Model.extend({
url: function() {
return _.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
}
});
在模型上设置idAttribute
这取决于您要传递的 id
在数据中的含义。
Backbone 模型使用 "id"
具有默认的 id 属性名称。您可以通过覆盖 idAttribute
property of the model. Whatever the name, it is always automatically made available through the model.id
property.
来指定不同的名称
现在,假设 id
属性与此模型无关并且此模型的真实 id 属性名称类似于 UID
,您可以更改模型的 idAttribute
反映属性的真实名称(或者它甚至可以是一个永远不会成为属性的字符串)。
var MyModel = Backbone.Model.extend({
idAttribute: 'UID',
});
现在,id
属性不被视为当前模型的 id,model.isNew()
将 return true
,发送一个 POST 请求在保存时创建它。
更改 sync
/save
函数行为
如果您使用的 API 不是 而不是 RESTful,您可以通过覆盖使用的 sync
function. This can be done on the model or collection, or on the Backbone.sync
function 来调整行为默认情况下由集合和模型。
例如,如果你想让每个请求默认使用 POST MyModel
class:
var MyModel = Backbone.Model.extend({
sync: function(method, model, options) {
return Backbone.sync.call(this, method, model,
_.extend({ type: 'POST' }, options));
}
});
您可以仅使用 save
函数来执行类似的操作,让 fetch
照常执行其 GET
请求。
使用emulateHTTP
setting2
If you want to work with a legacy web server that doesn't support
Backbone's default REST/HTTP approach, you may choose to turn on
Backbone.emulateHTTP
. Setting this option will fake PUT
, PATCH
and
DELETE
requests with a HTTP POST
, setting the X-HTTP-Method-Override
header with the true method.
[...]
Backbone.emulateHTTP = true;
model.save(); // POST to "/collection/id", with "_method=PUT" + header.
不要覆盖isNew
Has this model been saved to the server yet? If the model does not yet
have an id, it is considered to be new.
该站点上的一些其他答案建议覆盖 isNew
function。 不要。该函数有其目的,覆盖它以强制执行 POST 请求是一个糟糕的 hack,而不是解决方案。
isNew
仅供内部使用,但也可由您的代码或其他库和 Backbone 插件使用。
1 虽然我没有从堆栈溢出中获取它,但它已经是 an answer by Andrés Torres Marroquín on a similar question.
2 取自 Maanas Royy's answer.
我需要制作一个 POST 到服务器端 API。我必须将 id
密钥发送到服务器的请求正文中。
我使用 Backbone 模型。但是当我这样做时:
myModel.set("id", somevalue)
myModel.save()
触发的网络请求是:URL/someValue [PUT]
Backbones 不执行 POST 而是执行 PUT 并将 id 附加到 url.
所以我只想在 Backbone 不注意的情况下将 id
密钥传递给服务器。
Backbone is pre-configured to sync with a RESTful API.
[...]
The default
sync
handler maps CRUD to REST like so:
- create →
POST /collection
- read →
GET /collection[/id]
- update →
PUT /collection/id
- patch →
PATCH /collection/id
- delete →
DELETE /collection/id
新条目没有 ID,因此如果您在保存之前为模型提供 ID,Backbone 默认为 PUT 请求,因为它认为您要保存现有条目。
如何使用 id 发出 POST 请求?
选择以下解决方案之一。
坚持RESTfulAPI
这一个是显而易见的。可以的话,坚持标准。
更改 API 以处理 PUT/PATCH 请求并仅在创建时使用 POST。使 API 端点从 URL.
获取 ID传递type
选项1
简单且非常适合一次性情况。
传递给 save
(或 fetch
)的每个选项都会覆盖 sync
函数默认定义的选项并传递给 jQuery.ajax
function.
// Make the request, allowing the user to override any Ajax options. var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
var url = model.url(); // get the url before setting the `id`
model.save({
id: somevalue
}, {
url: url, // fix the url
type: 'POST' // choose the HTTP verb
});
修复模型使用的url很简单,你也有一些选择:
- 传递
url
选项(如上) - 覆盖模型的
url
function
重写 url
函数 (source) 适用于每次调用都应使用特定 url 而无需附加默认值 id
的情况。
var MyModel = Backbone.Model.extend({
url: function() {
return _.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
}
});
在模型上设置idAttribute
这取决于您要传递的 id
在数据中的含义。
Backbone 模型使用 "id"
具有默认的 id 属性名称。您可以通过覆盖 idAttribute
property of the model. Whatever the name, it is always automatically made available through the model.id
property.
现在,假设 id
属性与此模型无关并且此模型的真实 id 属性名称类似于 UID
,您可以更改模型的 idAttribute
反映属性的真实名称(或者它甚至可以是一个永远不会成为属性的字符串)。
var MyModel = Backbone.Model.extend({
idAttribute: 'UID',
});
现在,id
属性不被视为当前模型的 id,model.isNew()
将 return true
,发送一个 POST 请求在保存时创建它。
更改 sync
/save
函数行为
如果您使用的 API 不是 而不是 RESTful,您可以通过覆盖使用的 sync
function. This can be done on the model or collection, or on the Backbone.sync
function 来调整行为默认情况下由集合和模型。
例如,如果你想让每个请求默认使用 POST MyModel
class:
var MyModel = Backbone.Model.extend({
sync: function(method, model, options) {
return Backbone.sync.call(this, method, model,
_.extend({ type: 'POST' }, options));
}
});
您可以仅使用 save
函数来执行类似的操作,让 fetch
照常执行其 GET
请求。
使用emulateHTTP
setting2
If you want to work with a legacy web server that doesn't support Backbone's default REST/HTTP approach, you may choose to turn on
Backbone.emulateHTTP
. Setting this option will fakePUT
,PATCH
andDELETE
requests with a HTTPPOST
, setting theX-HTTP-Method-Override
header with the true method.[...]
Backbone.emulateHTTP = true; model.save(); // POST to "/collection/id", with "_method=PUT" + header.
不要覆盖isNew
Has this model been saved to the server yet? If the model does not yet have an id, it is considered to be new.
该站点上的一些其他答案建议覆盖 isNew
function。 不要。该函数有其目的,覆盖它以强制执行 POST 请求是一个糟糕的 hack,而不是解决方案。
isNew
仅供内部使用,但也可由您的代码或其他库和 Backbone 插件使用。
1 虽然我没有从堆栈溢出中获取它,但它已经是 an answer by Andrés Torres Marroquín on a similar question.
2 取自 Maanas Royy's answer.