我正在使用backbone.js与REST API交互,当发布到它创建新资源时,响应状态为201,“Location”标头指向资源的URI,但是空体
当我创建一个新模型时,它成功了,但模型的本地表示只包含我明确设置的属性,而不包含将在服务器上设置的任何属性(created_date等)< / p>
根据我的理解,Backbone将使用正文中的数据更新其模型的表示形式(如果有的话)。但是,既然没有,它就没有。
所以,显然,我需要使用Location标头中的位置来更新模型,但是最好的方法是什么。
我目前的心态是我必须从头部解析url,拆分id,设置模型的id,然后告诉模型fetch()。
这看起来非常混乱。有更清洁的方法吗?
我对API有一些影响。是尝试让API作者将新模型作为响应主体返回的最佳解决方案(保留201和位置标题)?
谢谢!
答案 0 :(得分:7)
听起来你必须做一点定制。 也许重写继承自的模型类的parse方法和url方法 Backbone.Model。
继承的功能是:
url : function() {
var base = getUrl(this.collection);
if (this.isNew()) return base;
return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + this.id;
},
parse : function(resp) {
return resp;
},
你可以尝试类似的东西:
parse: function(resp, xhr) {
this._url = xhr.getResponseHeader('location')
return resp
}
url: function() {
return this._url
}
答案 1 :(得分:5)
是的,backbone.js真的希望保存(可以是PUT或POST)的结果是一个可解析的主体,可用于更新模型。如果,如您所说,您对API有影响力,您应该看看是否可以安排内容正文包含资源属性。
正如您所指出的那样,进行第二次线上调用以完全实现模型毫无意义。
状态代码200可能更合适。纯粹主义者可能认为201状态代码意味着只返回一个位置而不是实体。显然,在这种情况下这没有意义。
答案 2 :(得分:2)
使用Backbone 0.9.9,我无法获得接受的工作答案。 parse
函数的签名似乎在旧版本中已更改,并且函数签名中不再提供xhr
对象。
这是我所做的一个例子,它使用Backbone v0.9.9和jQuery 1.8.3(使用Deferred Object/Promise),依赖于{{3}返回的jqXHR
object }:
window.CompanyView = Backbone.View.extend({
// ... omitted other functions...
// Invoked on a form submit
createCompany: function(event) {
event.preventDefault();
// Store a reference to the model for use in the promise
var model = this.model;
// Backbone.Model.save returns a jqXHR object
var xhr = model.save();
xhr.done(function(resp, status, xhr) {
if (!model.get("id") && status == "success" && xhr.status == 201) {
var location = xhr.getResponseHeader("location");
if (location) {
// The REST API sends back a Location header of format http://foo/rest/companys/id
// Split and obtain the last fragment
var fragments = location.split("/");
var id = fragments[fragments.length - 1];
// Set the id attribute of the Backbone model. This also updates the id property
model.set("id", id);
app.navigate('companys/' + model.id, {trigger: true});
}
}
});
}
});
我没有使用可以在success
函数提供的options
哈希中指定的Backbone.Model.save
回调,因为在收到XHR响应之前会调用该回调。也就是说,存储对jqXHR
对象的引用并在success
回调中使用它是没有意义的,因为当回调为jqXHR
时,Backbone.sync
将不包含任何响应头。调用
另一个解决此问题的方法是编写自定义{{1}}实现,但我不喜欢这种方法。