回答
當前主幹不支持將模型的一部分發送到服務器。這將是一個有趣的補充,但。
如果你browse the source你可以看到Backbone.sync
(負責與數據存儲通信的骨幹部分)是骨幹網中最簡單的組件之一,並簡單地將Ajax支持包裝在jQuery或Zepto中。
UPDATE
開始骨幹版本0.9.10,局部模型更新通過
model.save(attrs, {patch: true})
骨幹原生支持不支持這個開箱即用,但你擁有所有的工具做到這一點。 如果你看Backbone.sync,你會看到它在你的模型上調用JSON來獲取實際的數據發送。現在你可能要調整了這一點,但這裏是它的要點:
initialize: function(){
this.dirtyAttributes = {}
},
set: function(attrs, options){
Backbone.Model.prototype.set.call(this, attrs, options);
_.extend(this.dirtyAttributes, attrs);
},
toJSON : function(){
json = this.dirtyAttributes;
this.dirtyAttributes = {};
return json;
}
如果你想你需要同樣的邏輯適用於未設置,清晰,保存等完整的解決方案,但我猜你得到如何做到這一點。我把髒屬性的重置置於toJSON函數中,但它確實應該在成功回調中(當調用保存時)。
謝謝你的回答。我接受了另一個,因爲他速度更快:-)。 – ggarber 2011-03-11 16:08:37
@gustavogb好吧,謝謝讓StackOverflow變得更糟。 – 2012-07-12 14:03:17
我會更進一步,只標記爲實際已更改的髒屬性。將屬性值設置爲原始值(從服務器加載時)應將其標記爲乾淨(不再髒)。這在lib中會有意義嗎?我應該提交補丁嗎?請注意'{patch:true}'的當前行爲不會這樣做。 – 2013-04-30 13:01:10
如果您需要發送更新請求到服務器只是一個特定的屬性,你可以做同樣的事情:對
saveAttributes: (attributes, options={}) ->
data = {}
_(attributes).each (attribute) =>
data[attribute] = @get(attribute)
params =
data: $.param(data)
_.extend(params, options)
Backbone.sync('update', null, params)
更多信息:https://github.com/documentcloud/backbone/pull/573
您可以_.extend Backbone.Model.prototype
後面馬上將所有字段標記爲「髒」,我必須指定'A'url'屬性或函數。錯誤:必須指定'url'屬性或函數 backbone_rails_sync.js:15' – lulalala 2012-08-27 08:21:46
我嘗試了幾個這裏提出的技術,但最終決定直接修改Backbone.Model和Backbone.sync。我想提供的是提供這種功能的微創方法,它不需要指導我的團隊中的開發人員使用重要的主幹方法;太容易出錯。我的解決方案只涉及將選項傳遞給模型的「保存」方法。例如:
//Note that this could be from your view or anywhere you're invoking model.save
saveToModel : function() {
this.model.save({
field1 : field1Value,
field2 : field2Value,
field3 : field3Value
}, {partialUpdate : true}
}
現在,啓用此功能,我做了一些非常小的修改Backbone.Model.save和Backbone.sync。這裏的變化Backbone.Model.save:
//If a partialUpdate is required, create a member on the options
//hash called updateAttrs and set it to attrs
if (options.partialUpdate != "undefined" && options.partialUpdate) {
options.updateAttrs = attrs;
}
//--->>>Put the block above right above the return line
return (this.sync || Backbone.sync).call(this, method, this, options);
這裏會發生什麼情況是,如果partialUpdate作爲一個選項傳遞,然後一個新的成員被稱爲updateAttrs上的選項哈希創建。選項散列自動傳遞給Backbone.sync。
對於Backbone.sync,我改變了以下條件:
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
到...
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
//If doing a partial model update, then grab the updateAttrs member
//from options. Will not interfere with line directly below as params.data
//will have been set.
params.data = (options.partialUpdate != "undefined" && options.partialUpdate)
? params.data = JSON.stringify(options.updateAttrs)
: params.data = JSON.stringify(model.toJSON());
}
添加額外的條件檢查,看是否partialUpdate設置,那麼如果是,設置params.data到options.updateAttrs。這將被傳遞給jQuery Ajax方法。
UPDATE:開始骨幹版本0.9.10,部分更新是通過本地
model.save(attrs, {patch: true})
支持直到0.9.9 的一種方法,而不直接編輯Backbone.js的庫文件。只需將以下代碼添加到應用程序js文件中,並在backbone.js加載後加載它。
//override the Backbone.sync to send only the changed fields for update (PUT) request
var Original_BackboneSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
/* just handle the data picking logic for update method */
if (!options.data && model && method == 'update') {
options.contentType = 'application/json';
options.data = JSON.stringify(model.changedAttributes() || {});
}
//invoke the original backbone sync method
return Original_BackboneSync.apply(this, arguments);
};
//Tested in Backbone.js 0.9.1
這是一項很酷的技術。 – 2012-05-21 18:41:41
這個版本似乎比原生版更好! – exussum 2013-06-26 12:35:45
'changedAttributes'只包含最後一次調用到'.set()'的變化,所以如果你做了'm.set('p1',1); m.set('p2',2); m.save();'它只會發送'{p2:2}'不是所有更新的字段。 – CodingWithSpike 2016-03-15 20:50:12
而是覆蓋Backbone.sync
的,你可以做它的Model.sync
方法內。由於您無法在那裏訪問model.changedAttributes()
,請務必在此方法內始終返回false。
sync: (method, model, options) ->
if method is "update"
options.contentType = 'application/json'
changedData = {}
for attr in _.keys(options.changes)
changedData[attr] = model.get(attr)
options.data = JSON.stringify changedData
Backbone.sync method, model, options
使用Jayyy V的(非常好)的答案,我重寫它一點點,使同步功能採取白名單,所以你可以給它得到保存鍵數組。
var Original_BackboneSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
/* check if a whitelist was in options */
if (options.whitelist) {
options.contentType = 'application/json';
/* use underscore method for picking only whitelisted attributes to save */
options.data = JSON.stringify(_.pick(model.attributes, options.whitelist));
}
//invoke the original backbone sync method
return Original_BackboneSync.apply(this, arguments);
};
這裏的大多數答案是直接或間接修改sync
函數。這是我的小技巧來解決這個問題:
當你打電話給model.save
時,你實際上可以傳入第二個參數,當Backbone嘗試調用同步時將傳遞給$.ajax
。我不喜歡這樣的部分更新,更明確地規定哪些字段提交:
/**
* On user clicking on "mark important"
*/
onMarkImportantBtnClick: function() {
var marked = this.model.get('UserFeed.marked_important'),
data = {
UserFeed: {
marked_important: !marked
}
};
this.model.save(data, {data: JSON.stringify(data), contentType: 'application/json'});
}
這個動作更新我的模型正確的屬性,加上發送到在JSON.stringify
提到的服務器只能將資料。 contentType
這裏需要,更好地
這是因爲Backbone.sync
has these lines,並且我們通過傳遞data
屬性否定它:
if (!options.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
信用此頁:https://plus.google.com/103858073822961240171/posts/1gTcu6avmWQ
注:該模型繼承自powmedia的DeepModel以支持嵌套模型屬性
編輯自骨幹0.9.9,patch
選項已被添加
所以這一招只適用於以前的版本。
要只提交髒數據傳回服務器,供應{patch: true}
在save
,這樣
this.model.save(modifiedData, {patch: true});
感謝@Lincoln B中指點一下。
最好的答案在這裏,謝謝你的來源。 Backbone 0.9.9增加了{path:true}來保存,但是如果你現在不能升級,這是理想的事情。我個人定義了一個單獨的補丁,如補丁:(attributes,options = {}) - > this.save(attributes,{data:JSON.stringify(attributes)}) – 2013-01-17 23:41:38
是的。此解決方案僅適用於較舊的Backbone版本。新的「補丁」很酷! – 2013-01-18 01:41:58
在@ Julien的帖子上創建: 您可以將其添加到您的模型中,它只會發送您傳入的屬性,而不是整個模型。您仍然可以使用save作爲默認行爲,並且您可以在發送那些作爲參數傳入的屬性時使用partialSave。我已經測試過了,它對我有用。
partialSave: function(attr, options) { //use this method instead of save()
this.dirtyAttributes = attr;
this.save(attr, options);
},
toJSON: function() { //overrides Backbone.Model.prototype.toJSON
if (this.dirtyAttributes) {
var attr = this.dirtyAttributes;
this.dirtyAttributes = null;
return attr;
}
return Backbone.Model.prototype.toJSON.apply(this, arguments);
},
事實上,有實現這一
的更簡單的方法,如果你看一下Backbone.js的線1145,你會看到
// Ensure that we have the appropriate request data.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.contentType = 'application/json';
params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
這意味着你可能會覆蓋數據部分xhr通過將數據放入您的選項
由於骨幹保存需要model.save([attributes], [options])
但請記住,屬性,如ID可能是必要的適當的儲蓄
例
model.save({}, { data: JSON.stringify(data) }) ;
所以,你應該做這樣的事情
var data = { id : model.id , otherAttributes : 'value' } ;
或
var data = model.toJSON() ;
remove data.tempData ;
最後
model.save({}, { data : JSON.stringify(data) });
該做的伎倆相當不錯的我,還可能與XHR如獲取,保存,刪除,任何骨幹網使用...
與保存,同步或看的toJSON這樣的錯誤
梅辛我創建了擴展模型。用法
var CModel = Backbone.Model.extend({
save: function(attributes, options) {
if(_.isUndefined(options)) {
options = {};
}
var isNeedAttrsRefresh = false,
basicAttributes = null;
if(!_.isUndefined(options.fields)) {
basicAttributes = _.clone(this.attributes);
var newAttributes = {};
_.each(this.attributes, function(value, name) {
if(options.fields.indexOf(name) > -1) {
newAttributes[name] = value;
}
});
this.attributes = newAttributes;
isNeedAttrsRefresh = true;
}
this.isSaving = true;
var result = Backbone.Model.prototype.save.apply(this, arguments);
this.isSaving = false;
if(isNeedAttrsRefresh) {
this.attributes = basicAttributes;
}
return result;
}
});
例子:
var CommentModel = CModel.extend({ ... }
,並允許領域節省:
comment.save(null, { fields: ['message', 'entry_id', 'module_id', 'parent_id'] });
- 1. backbone.js:如何使用.set()部分更新模型json對象?
- 2. 更新模型的一部分
- 3. 更新部分映射模型
- 4. 在Rails中部分更新模型3
- 5. 只更新模型的一部分
- 6. backbone.js:更新模型,重新排序和重新渲染模型集合
- 7. backbone.js在視圖更改時更新模型的正確方法
- 8. 模型Backbone.js的
- 9. Backbone.js模型
- 10. Backbone.js - 與另一個視圖共享模型的一部分
- 11. 在backbone.js中更改視圖的模型
- 12. Backbone.js模型緩存
- 13. 運輸backbone.js模型?
- 14. backbone.js複雜模型
- 15. 如何更新集合中的所有模型 - Backbone.js
- 16. 在Backbone.js中處理模型更新服務器響應
- 17. 在不擦除舊模型的情況下更新Backbone.js集合
- 18. 保存Backbone.js模型並更新整個集合
- 19. 更新模型W/Backbone.js的+ Rails的工作不
- 20. Backbone.js從服務器就地更新模型
- 21. backbone.js批量更新
- 22. 更新部分
- 23. 的EntityFramework更新局部模型
- 24. JQuery Sortable + Rails - 更新外部模型
- 25. 部分模型驗證在創建/更新方案
- 26. 如何在MVC5的部分視圖中更新視圖模型?
- 27. 只更新模型的一部分,驗證問題?
- 28. Knockout.js映射。如何只更新視圖模型的一部分?
- 29. MVC - 部分在視圖中更新模型
- 30. Backbone.js的更改模型的URL參數,並獲取不更新數據獲取
這是現在支持爲0.9.9版本,如果你只希望改變的屬性發送到服務器,調用model.save(attrs,{patch:true})。只需傳入的屬性即可獲得到服務器的HTTP PATCH請求。 http://backbonejs.org/#Model-save – Ben 2013-01-06 19:18:50