保存模型時,骨幹決定是否通過設置模型的ID屬性來發送HTTP POST
或PUT
請求。如果有一個ID,則認爲該模型已經存在。允許用戶在創建時指定骨幹模型的ID
對於我的應用程序,這種邏輯是不正確的,因爲我必須允許用戶指定一個ID(因爲我與一個設計不良的遺留系統交互)。
我應該如何處理這個問題?如果模型更改,我仍然想使用PUT
。
我正在考慮以下選項:
- 覆蓋
isNew
,這是簡單地檢查如果ID是本骨幹方法。 - 覆蓋
sync
。 - 確定
cid
的概念是否能以某種方式解決問題。
保存模型時,骨幹決定是否通過設置模型的ID屬性來發送HTTP POST
或PUT
請求。如果有一個ID,則認爲該模型已經存在。允許用戶在創建時指定骨幹模型的ID
對於我的應用程序,這種邏輯是不正確的,因爲我必須允許用戶指定一個ID(因爲我與一個設計不良的遺留系統交互)。
我應該如何處理這個問題?如果模型更改,我仍然想使用PUT
。
我正在考慮以下選項:
isNew
,這是簡單地檢查如果ID是本骨幹方法。sync
。cid
的概念是否能以某種方式解決問題。這裏的另一種解決方案:
在模型中定義不存在於您的服務器型號/表中的idAttribute/...這將不會被顯示給DOM。
所以,讓我們假設您發送到服務器的JSON如下:
{
'id': 1,
'name': 'My name',
'description': 'a description'
}
你的模型應該是這樣的:
var MyModel = Backbone.Model.extend({
idAttribute: 'fakeId'
});
現在,當你創建一個新的模型,並嘗試要將其保存到服務器,沒有人會初始化fakeId
,並將其視爲新對象(POST)。
當你從服務器抓取你的模型,你必須設置fakeId在你的模型,你的服務器必須在fakeId
你這樣的模式將被視爲現有(PUT)
甜蜜的時機,因爲我現在自己處理這個問題。我不喜歡這個解決方案,因爲如果ID是可編輯的,你現在需要保持這兩個同步,你的服務器現在需要知道Backbone中的這個限制。不知道該修復應該是什麼,但它應該完全包含在Backbone中。 –
一個複製id
解決辦法是解決症狀而不是原因。考慮添加到您的模型的新方法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困擾我,因爲我的用例(儘管工作和相當小),但也許它適用於你的。
我很想看到這個問題的一些額外的答案。
也許你可以重載「保存」而不是添加「創建」。 –
@DonaldTaylor但是那麼如何不對編輯執行POST覆蓋? –
所以我沿着試圖改變的路徑isNew
。
我想出了新的標準,從而回答模型是否是新的:
new Model({ id: 1, name: 'bob' })
不考慮新的,而以後(new Model({ name: bob'}).set('id', 1)
)將設置ID。這裏是這個樣子:
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檢查,以解決這個問題,但後來從現有派生其數據的新模型的任何建設將被作爲新治療(在我的情況,這是不可取的)。
你應該考慮接受一個答案。 :) –