同步时排除模型属性(Backbone.js)

当我同步时,是否有办法从我的模型中排除某些属性?

例如,我在我的模型信息中保留了一些视图状态。 比方说,我有一个select器模块,这个模块只是在我的模型上切换selected属性。 后来,当我在我的集​​合上调用.save()时,我想忽略selected的值,并将其从同步到服务器中排除。

有没有一个干净的方式呢?

让我知道你是否想要更多的细节

这似乎是最好的解决scheme(基于@nikoshr引用的问题)

 Backbone.Model.extend({ // Overwrite save function save: function(attrs, options) { options || (options = {}); attrs || (attrs = _.clone(this.attributes)); // Filter the data to send to the server delete attrs.selected; delete attrs.dontSync; options.data = JSON.stringify(attrs); // Proxy the call to the original save function return Backbone.Model.prototype.save.call(this, attrs, options); } }); 

所以我们在模型实例上覆盖了保存函数,但是我们只是过滤掉了我们不需要的数据,然后我们将其代理到父级原型函数中。

在Underscore 1.3.3中,他们添加了pick和in 1.4.0,他们添加了omit ,它可以很简单地用你的模型的toJSON函数把_.pick或者blacklist属性白名单join_.omit

而且由于toJSON被sync命令用于将数据传递给服务器,所以我认为这是一个很好的解决scheme,只要你不需要这些字段,无论你使用toJSON使用toJSON

 Backbone.Model.extend({ blacklist: ['selected',], toJSON: function(options) { return _.omit(this.attributes, this.blacklist); }, }); 

我的解决scheme结合了以上所有。 只是使用白名单而不是黑名单..这是一般的好规则

确定

  attrWhiteList:['id','biography','status'], 

然后覆盖保存

  save: function(attrs, options) { options || (options = {}); //here is whitelist or all if (this.attrWhiteList != null ) // Filter the data to send to the server whitelisted = _.pick(this.attributes, this.attrWhiteList); else whitelisted =this.attributes; /* it seems that if you override save you lose some headers and the ajax call changes*/ // get data options.data = JSON.stringify(whitelisted); if ((this.get('id') == 0) || (this.get('id') == null)) options.type = "POST" else options.type = "PUT"; options.contentType = "application/json"; // options.headers = { // 'Accept': 'application/json', // 'Content-Type': 'application/json' // }, // Proxy the call to the original save function return Backbone.Model.prototype.save.call(this, attrs, options); }, 

事实上,有一个更简单的方法来实现这一点,而不会干扰主干保存或同步function,因为你不会期望这种行为是永久的

如果你看看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' } ; model.save( {}, { data : JSON.stringify(data) } ); 

这个技巧对我来说很好,可以和任何支持xhr的骨干一起使用,例如抓取,保存,删除,…

基于几个答案,这将解决null对象的情况,以及Backbone中的条件,如果options.data已经设置,则不发送contentType

 EDITABLE_ATTRIBUTES = ["name", "birthdate", "favoriteFood"]; ... save: function(attrs, options) { // `options` is an optional argument but is always needed here options || (options = {}); var allAttrs = _.extend({}, this.attributes, attrs); var allowedAttrs = _.pick(allAttrs, EDITABLE_ATTRIBUTES); // If `options.data` is set, Backbone does not attempt to infer the content // type and leaves it null. Set it explicitly as `application/json`. options.contentType = "application/json"; options.data = JSON.stringify(allowedAttrs); return Backbone.Model.prototype.save.call( this, allowedAttrs, options); }, 

save使用toJSON我们覆盖它:

  toJSON: function(options) { var attr = _.clone(this.attributes); delete attr.selected; return attr; }, 

但是,如果您使用toJSON并且需要在视图中selected ,则它可能不起作用。 否则,你可能需要重写save方法。

设置options.attrs将允许你自定义API参数:

 var model = new Backbone.Model(); model.save(null, { wait: true, success: function() { }, attrs: _.omit(model.attributes, 'selected') }); 

我发现接受的解决scheme有一些问题,因为options.data修改了骨干进行呼叫的方式。 更好地使用options.attrs,如下所示:

 Backbone.Model.extend({ save: function (attrs, options) { options = options || {}; attrs = _.extend({}, _.clone(this.attributes), attrs); // Filter the data to send to the server delete attrs.selected; options.attrs = attrs; // Proxy the call to the original save function return Backbone.Model.prototype.save.call(this, attrs, options); } }); 

如果是一次性的,你可以使用mode.unset('selected', { silent:true }) (沉默只是为了避免触发变化事件),删除属性…这有没有所以保存后不得不重新设置它的好反效果。

这就是说,我完全赞同上面的解决scheme之一。 此外,如果这是你需要更经常的事情。

要仅设置所需的值,请使用HTTP POST的HTTP PATCH insead。 在骨干端,只需要在save方法中添加一个补丁属性:

 entity.save(data,{patch:true}) 

使用此属性保存,只有在data发送到服务器时传递的字段。

有同样的问题,我决定创build一个小模块,可以帮助: https : //github.com/lupugabriel1/backbone-model-save

这就是你可以在你的模型中使用它的方法:

 var myModel = new Backbone.ModelSave.extend({ notSync: ['name', 'age'] });