Exclude model properties when syncing (Backbone.js)

后端 未结 11 1398
甜味超标
甜味超标 2020-12-07 14:26

Is there a way to exclude certain property from my model when I sync?

For example, I keep in my model information about some view state. Let\'s say I have a picker m

相关标签:
11条回答
  • 2020-12-07 14:28

    I found some problems with the accepted solution, as options.data modifies the way Backbone makes the calls. Better using options.attrs as this:

    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);
        }
    });
    
    0 讨论(0)
  • 2020-12-07 14:28

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

    This is how you can use it in your models:

    var myModel = new Backbone.ModelSave.extend({
        notSync: ['name', 'age']
    });
    
    0 讨论(0)
  • 2020-12-07 14:35

    my solution combine all the above. just use white list instead of black one .. this is 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);
    },
    
    0 讨论(0)
  • 2020-12-07 14:41

    Based on several of the answers, this accounts for cases of null objects and a conditional in Backbone that doesn't sent the contentType if options.data is 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);
    },
    
    0 讨论(0)
  • 2020-12-07 14:46

    Since save uses toJSON we override it:

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

    But it may not work if you're using toJSON and need selected in views for example. Otherwise you probably need to override save method.

    0 讨论(0)
  • 2020-12-07 14:47

    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 model's toJSON function to whitelist attributes with _.pick or blacklist attributes with _.omit.

    And since toJSON is used by the sync command for passing the data to the server I think this is a good solution as long as you do not want these fields wherever else you use toJSON.

    Backbone.Model.extend({
        blacklist: ['selected',],
        toJSON: function(options) {
            return _.omit(this.attributes, this.blacklist);
        },
    });
    
    0 讨论(0)
提交回复
热议问题