我在模型中使用复合键,并根据我的复合键生成ID:
app.Assignment = Backbone.Model.extend({
idAttribute : [ 'personId', 'jobId' ],
parse : function(resp) {
resp.id = resp.personId + "_" + resp.jobId;
return resp;
}
});
但是Backbone仍然认为Assignment的所有实例都是新的,尽管我在从API中获取它时在parse方法中设置了id。因此,Backbone没有DELETE,并且在更新时执行POST而不是PUT。我该如何解决这个问题或者“正确的方法”呢?
更新
看起来用this.id替换resp.id解决了这个问题。
答案 0 :(得分:2)
Backbone.Model的parse
方法的结果传递给set
方法,该方法设置模型的属性。我认为,混淆点是模型的ID不是它的属性之一;它是属性之一。
那么,会发生什么:
parse
id
属性进行扩充的相同原始数据将传递到set
set
看起来和您的idAttribute
([ 'personId', 'jobId' ]
)以及原始数据中的所有密钥idAttribute
,因此没有一个密钥用作模型的ID,因此您就会遇到问题。您在this.id
内设置parse
的解决方案有效,但它可能会导致问题,因为解析通常设计为对其输入(原始数据)进行操作,而不是修改模型本身;该部分应该在调用set
时发生。更清洁的解决方案是做类似以下的事情:
app.Assignment = Backbone.Model.extend({
// note that no idAttribute is specified, leaving it as the default "id"
parse : function(resp) {
resp.id = resp.personId + "_" + resp.jobId;
return resp;
}
}
或者,如果你想要一个不同的ID属性......
app.Assignment = Backbone.Model.extend({
idAttribute: 'personAndJobId',
parse : function(resp) {
resp.personAndJobId = resp.personId + "_" + resp.jobId;
return resp;
}
}
答案 1 :(得分:0)
除了此处的idAttribute
问题之外,您始终可以通过传递给save()
的类型选项强制Backbone使用某种HTTP方法。
model.save(null, { type: 'put' })
答案 2 :(得分:0)
我从未在Backbone中使用复合ID,但我认为这可以很容易地解决您的问题:
initialize: function() {
this.set("id", this.generateID());
},
generateID = function () {
return this.personId + + "_" + this.jobId;
}
在Backbone模型定义中使用此代码,您将为每个模型创建一个唯一的ID,您不应该遇到更新问题并保存它(并且您不需要设置任何idAttribute)。