保存模型时,Backbone根据是否设置了模型的ID属性来确定是发送HTTP POST
还是PUT
请求。如果有ID,则认为该模型已存在。
对于我的应用程序,这个逻辑是不正确的,因为我必须允许用户指定一个ID(因为我与设计不良的遗留系统进行交互)。
我该如何处理这个问题?如果模型被更改,我仍然想使用PUT
。
我正在考虑以下选项:
isNew
,这是一种只检查ID是否存在的Backbone方法。sync
。cid
的概念是否会以某种方式解决问题。答案 0 :(得分:1)
一种解决方案是解决症状而不是原因。考虑向您的模型添加新的create
方法:
var FooModel = Backbone.Model.extend({
urlRoot: '/api/foo',
create: function () {
return this.save(null, {
type: 'post', // make it a POST rather than PUT
url: this.urlRoot // send the request to /api/foo rather than /api/foo/:id
});
}
});
这是我使用的解决方案,但我不认为这是理想的,因为视图逻辑/调用者现在需要在创建时调用create
而不是save
(这很容易) 。这个扩展的API困扰我的用例(尽管工作和相当小),但也许它对你的用途。
我很想看到这个问题的其他答案。
答案 1 :(得分:1)
所以我走上了试图改变isNew
的道路。
我提出了新的标准,可以回答模型是否是新的:
new Model({ id: 1, name: 'bob' })
不能被视为新的,而稍后设置ID(new Model({ name:
bob'}).set('id', 1)
)将是。这是这样的:
var UserDefinedIDModel = Backbone.Model.extend({
// Properties
_wasCreatedWithID: false,
_wasConstructedByFetch: false,
_wasSynced: false,
// Backbone Overrides
idAttribute: 'some_id',
urlRoot: '/api/foo',
constructor: function (obj, options) {
this._wasCreatedWithID = !!obj[this.idAttribute];
this._wasConstructedByFetch = options && options.xhr && options.xhr.status === 200;
// Preserve default constructor
return Backbone.Model.prototype.constructor.apply(this, arguments);
},
initialize: function () {
this.on('sync', this.onSync.bind(this));
},
isNew: function () {
// We definitely know it's not new
if (this._wasSynced || this._wasConstructedByFetch) return false;
// It might be new based on this. Take your pick as to whether its new or not.
return !this._wasCreatedWithID;
},
// Backbone Events
onSync: function () {
this._wasSynced = true;
}
});
优于其他答案
<强>缺点强>
create
方法时,这是很多代码。myCollection.create({ some_id: 'something' });
发出PUT。我想如果您需要支持,则必须执行myCollection.create({ some_id: 'something' }, { url: '/api/foo', type: 'post' });
您可以删除_wasCreatedWithoutID检查以解决此问题,但是从现有模型中获取数据的任何新模型构造都将被视为新的(就我而言,这是不可取的)。答案 2 :(得分:0)
这是另一种解决方案:
在你的模型中定义一个idAttribute,它在你的服务器模型/ table / ...中不存在,并且不会显示给DOM。
因此,假设您发送到服务器的JSON如下:
{
'id': 1,
'name': 'My name',
'description': 'a description'
}
您的模型应如下所示:
var MyModel = Backbone.Model.extend({
idAttribute: 'fakeId'
});
现在,当您创建新模型并尝试将其保存到服务器时,没有人会初始化fakeId
,它将被视为新对象(POST)。
当您从服务器获取模型时,您必须在模型中设置fakeId,并且您的服务器必须复制id
中的fakeId
,因此您的模型将被视为现有模型( PUT)