Exclude model properties during synchronization (Backbone.js)

Is there a way to exclude a specific property from my model during synchronization?

For example, I store information about a view state in my model. Let's say I have a collector, and this module simply switches the selected attributes to my model. Later, when I call .save() in my collection, I want to ignore the selected value and exclude it from synchronization to the server.

Is there a clean way to do this?

(let me know if you want more details)

+42
Oct 24
source share
11 answers

This seems like a better solution (based on @nikoshr asked question)

 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); } }); 

Thus, we overwrite the save function in the model instance, but we just filter out the data that we do not need, and then we proxy the server to the original prototype function.

+47
Oct 24
source share

In Underscore 1.3.3 they added pick , and in 1.4.0 they added omit , which can be used very simply to override your toJSON model for whitelist attributes with _.pick attributes or blacklist using _.omit .

And since toJSON used by the sync command to transfer data to the server, I think this is a good solution if you do not want to use these fields wherever you use toJSON .

 Backbone.Model.extend({ blacklist: ['selected',], toJSON: function(options) { return _.omit(this.attributes, this.blacklist); }, }); 
+33
Mar 20 '13 at 15:43
source share

my solution combines all of the above. just use whitelist instead of blacklist. This is a good rule in general.

define

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

and then overwrite the save

  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); }, 
+11
Jul 19 '13 at 17:01
source share

In fact, there is a much simpler way to achieve this without entering into the functions of saving or synchronizing with the database, since you would not expect this behavior to be constant.

if you look at the line backbone.js 1145, you will see that

 // 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)); } 

This means that you can override the xhr data part by putting the data in your parameters

Since saving the base requires model.save ([attributes], [options])

But remember that attributes, such as id, may be necessary for proper storage.

Example

 model.save( {}, { data: JSON.stringify(data) } ) ; 

So you should do something like this

 var data = { id : model.id , otherAttributes : 'value' } ; model.save( {}, { data : JSON.stringify(data) } ); 

This works well for me and can be used with any framework with xhr, e.g. with fetch, save, delete, ...

+6
Aug 04
source share

Based on a few answers, this takes into account cases of null objects and conditional conditions in Backbone that did not send contentType if options.data already set:

 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); }, 
+3
Mar 26 '14 at 23:25
source share

Since save uses toJSON , we override it:

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

But this may not work if you use toJSON and, for example, need selected views. Otherwise, you may have to override the save method.

+2
Oct 24
source share

Set options.attrs will allow you to configure api param:

 var model = new Backbone.Model(); model.save(null, { wait: true, success: function() { }, attrs: _.omit(model.attributes, 'selected') }); 
+2
Jul 10 '14 at 7:03
source share

I found some problems with the decision made, since options.data changes the way Backbone is called. It is better to use options.attrs as follows:

 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); } }); 
+2
Feb 10 '15 at 16:05
source share

If this is a one-time case, you can use mode.unset('selected', { silent:true }) (silent is set only to avoid triggering the change event) to remove the attribute ... This has a not-so-good counter-effect if necessary reinstall it after saving.

This suggests that I fully support one of the solutions above. Moreover, if this is what you need on a regular basis.

0
Oct 27 '12 at 16:35
source share

To set only the desired values, use the HTTP PATCH insead HTTP POST. On the main side, just add the patch attribute to the save method:

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

Using storage with this attribute, only those fields that are transmitted as data are sent to the server.

0
Aug 18 '14 at 13:09 on
source share

Having the same problem, I decided to create a small module that can help: https://github.com/lupugabriel1/backbone-model-save

Here's how you can use it in your models:

 var myModel = new Backbone.ModelSave.extend({ notSync: ['name', 'age'] }); 
0
Sep 25 '14 at 17:46
source share



All Articles