清除除骨干模型之外的所有属性

时间:2018-02-02 21:49:12

标签: javascript backbone.js backbone-events backbone-model

我的模型具有比默认属性更多的属性。我需要在conda activate env-name更改时清除所有属性并将其设置回默认值,这样我就不会携带不必要的属性。

由于guest事件,清除所有属性并设置默认值会导致无限循环。

如何删除除一个属性之外的所有属性?
当模型属性设置回默认值时,有没有办法不触发另一个更改事件?
或删除默认值中未列出的任何内容?

这是我的模特

change:guest

我听'客人'变更事件

defaults: {
  _id: 'id',
  first_name: 'first_name',
  last_name: 'last_name',
  guest: true
}

更改事件调用this.on('change:guest', this.reset); 来更新模型,显然这会导致无限循环。

reset

1 个答案:

答案 0 :(得分:1)

I have made a reset function您可以轻松添加到基础Backbone模型。我将有关此解决方案的更多详细信息转入another answer

这比简单的.clear后跟.set更好,因为它将defaults合并回模型,让任何传递attributes都像初始化一样覆盖它们。

/**
 * Clears the model's attributes and sets the default attributes.
 * @param {Object} attributes to overwrite defaults
 * @param {Object} options to pass with the "set" call.
 * @return {Backbone.Model} this object, to chain function calls.
 */
reset: function(attributes, options) {
    options = _.extend({ reset: true }, options);

    // ensure default params
    var defaults = _.result(this, 'defaults'),
        attrs = _.defaults(_.extend({}, defaults, attributes || {}), defaults);

    // apply
    this._reset(attrs, options);

    // triggers a custom event, namespaced to model in order
    // to avoid collision with collection's native reset event
    // when listening to a collection.
    if (!options.silent) this.trigger('model:reset', this, options);

    return this;
},

/**
 * Private method to help wrap reset with a custom behavior in child
 * classes.
 * @param {Object} attributes to overwrite defaults
 * @param {Object} options to pass with the "set" call.
 */
_reset: function(attrs, options) {
    this.clear({ silent: true }).set(attrs, options);
},

然后你的模特:

var MyModel = BaseModel.extend({
    idAttribute: '_id',
    defaults: {
        first_name: 'first_name',
        last_name: 'last_name',
        guest: true
    },
    initialize: function() {
        this.listenTo(this, 'change:guest', this.onGuestChange);
    },
    onGuestChange: function(model, value, options) {
        this.reset(null, { silent: true });
    }
});

这样,您可以更灵活地使用guest处理程序更改onGuestChange时发生的情况,从而可以随心所欲地调用reset,{{1}选项。

概念证明

{ silent: true }
var BaseModel = Backbone.Model.extend({
  /**
   * Clears the model's attributes and sets the default attributes.
   * @param {Object} attributes to overwrite defaults
   * @param {Object} options  to pass with the "set" call.
   * @return {Backbone.Model}  this object, to chain function calls.
   */
  reset: function(attributes, options) {
    options = _.extend({
      reset: true
    }, options);

    // ensure default params
    var defaults = _.result(this, 'defaults'),
      attrs = _.defaults(_.extend({}, defaults, attributes || {}), defaults);

    // apply
    this._reset(attrs, options);

    // triggers a custom event, namespaced to model in order
    // to avoid collision with collection's native reset event
    // when listening to a collection.
    if (!options.silent) this.trigger('model:reset', this, options);

    return this;
  },

  /**
   * Private method to help wrap reset with a custom behavior in child
   * classes.
   * @param  {Object} attributes to overwrite defaults
   * @param  {Object} options  to pass with the "set" call.
   */
  _reset: function(attrs, options) {
    this.clear({
      silent: true
    }).set(attrs, options);
  },
})


var MyModel = BaseModel.extend({
  defaults: {
    first_name: 'first_name',
    last_name: 'last_name',
    guest: true
  },
  initialize: function() {
    this.listenTo(this, 'change:guest', this.onGuestChange);
  },
  onGuestChange: function(model, value, options) {
    this.reset(null, {
      silent: true
    });
  }
});

var model = new MyModel({
  first_name: 'test',
});
console.log('before:', model.attributes);
model.set('guest', false);

console.log('after:', model.attributes);

您无需克隆默认值即可使用它们。如果它们有数组或嵌套对象,<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>应该是返回对象的函数。

defaults

然后,使用_.result调用默认值:defaults: function() { return { arr: [], nested: { prop: 'test' } }; }, ,就像我的重置功能一样。 Backbone documentation on defaults有此通知:

  

请记住,在JavaScript中,对象是通过引用传递的,因此如果将对象包含为默认值,则它将在所有实例之间共享。相反,将默认值定义为函数。