Backbone模型的save()方法没有将ID追加到URL末尾

15

我有一个问题,使用backbone进行PUT请求时返回405(方法不允许)错误。问题出在代码中的model.save()没有在URL末尾附带模型的ID。

这是PUT请求。

Remote Address:::1:670
Request URL:http://localhost:670/api/contacts
Request Method:PUT
Status Code:405 Method Not Allowed
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Authorization:Bearer YLPwKSpBsBrFUemRHdjz....
Connection:keep-alive
Content-Length:417
Content-Type:application/json
Host:localhost:670
Origin:http://localhost:660
Referer:http://localhost:660/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)     Chrome/34.0.1847.116 Safari/537.36
Request Payloadview source
{id:1, ContactOrganisation:Cow on a Mission, ContactPerson:Ben Drury, Phone:07980567574,}
Address: "----"
ContactOrganisation: "----"
ContactPerson: "Ben"
CreatedBy: "----"
CreatedOn: "2014-03-03T16:40:50.037"
Description: "----"
Email: "---"
Organistion: "----"
Phone: "----"
Website: "http://www.cogiva.com"
id: 1
Response Headersview source
Access-Control-Allow-Headers:Authorization, Content-Type
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Allow:GET,POST,OPTIONS
Cache-Control:no-cache
Content-Length:72
Content-Type:application/json; charset=utf-8
Date:Thu, 17 Apr 2014 13:56:38 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
ConsoleSearchEmulationRendering
如果我通过 REST 控制台实现,将 ID 添加到 URL 中,它就能正常工作。但是直接从这段代码实现:
      this.model.set($(e.currentTarget).data("modelfield"), $(e.currentTarget).val());
      console.log("model",this.model);
      this.model.save({
          success: function(model, response){
            console.log("Yup!");
            $(self.el).find('.update_loader').removeClass("running");
            $(self.el).find('.update_loader').addClass("done");
          },
          error: function(){
            console.log("No!");
            $(self.el).find('.update_loader').removeClass("running");
            $(self.el).find('.update_loader').addClass("error");                
          }
      });

发布帖子前控制台上的模型明确有一个ID。那么为什么它不能正确地形成URL?

模型定义:

define([
'jquery',
'underscore',
'backbone',

], function ($, _, Backbone){

    var ContactModel = Backbone.Model.extend({
      url: "http://localhost:670/api/contacts"        
    });

    return ContactModel;

});

看起来 id 被放在了 body 中作为一个属性。这可能有很多原因。你是否覆盖了模型集合的 url - Gildor
不,这不是在代码中设置的,它只在模型定义中设置。 - Ben Drury
你能分享定义代码吗? - Gildor
没问题。已添加。 - Ben Drury
3个回答

21

设置Model.url只会为模型提供一个常量URL。如果您想要附加模型ID,则需要指定Model.urlRoot。这将生成以下形式的URL:“/api/contacts/id”:

设置Model.url只会为模型提供一个固定的URL。如果您想要添加模型的ID,则需要指定Model.urlRoot。这将生成形如“/api/contacts/id”的URL:

var ContactModel = Backbone.Model.extend({
  urlRoot: "http://localhost:670/api/contacts"        
});

或者,如果模型存储在集合中,则可以将Collection.url设置为相同的值。请参见Model.url的注释:

委托给Collection#url生成URL,因此请确保定义了它或urlRoot属性,如果此类的所有模型共享公共根URL。一个具有id为101的模型,存储在具有url"/documents/7/notes"的Backbone.Collection中,将具有此URL:"/documents/7/notes/101"


我相信这是正确的,根据我所读的内容,但是它对我没有起作用,我不知道为什么。 - Alexander Mills
对于想要删除末尾ID的人,我使用了“url”而不是“urlRoot”。所以它可以两种方式都工作,当然啦。 :) - Mehul Tandale

3
你覆盖了url属性,这就是为什么它是固定的 - backbone调用此属性/函数获取url。而默认的url函数实现使用urlRoot。将代码更改为以下内容应该可以工作:
var ContactModel = Backbone.Model.extend({
  urlRoot: "http://localhost:670/api/contacts"        
});

请看这里:model.url

如果你的url格式有特殊要求(不是urlRoot/id),你需要重写url函数以提供自定义实现。


2
您通过在ContactModel定义中设置显式的url属性来掩盖Model.url的默认行为。请改用Model.urlRoot
var ContactModel = Backbone.Model.extend({
  urlRoot: "http://localhost:670/api/contacts"        
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接