清除 Backbone 模型中除一个属性之外的所有属性
Clear all attributes except one on a Backbone Model
我有一个模型,其属性比默认属性多。我需要在 guest
更改时清除所有属性并设置回默认值,这样我就不会携带不必要的属性。
由于 change:guest
事件,清除所有属性并设置回默认值会导致无限循环。
如何删除除一个属性之外的所有属性?
当模型属性设置回默认值时,有没有办法不触发另一个更改事件?
或者删除默认值中未列出的任何内容?
这是我的模特
defaults: {
_id: 'id',
first_name: 'first_name',
last_name: 'last_name',
guest: true
}
我听'guest'改变事件
this.on('change:guest', this.reset);
更改事件调用 reset
来更新模型,显然这会导致无限循环。
reset: function() {
var new_defaults = _.clone(this.defaults);
this.clear({silent: true});
this.set(new_defaults);
}
I have made a reset
function that you can easily add to a base Backbone model. I go into more details about this solution into another answer.
它比简单的 .clear
followed by a .set
because it merges the 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
,这里使用 { 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
应该是一个返回对象的函数。
defaults: function() {
return {
arr: [],
nested: { prop: 'test' }
};
},
然后,使用_.result
to call the defaults: _.result(this, 'defaults')
like in my reset function. The Backbone documentation on defaults
有这个通知:
Remember that in JavaScript, objects are passed by reference, so if you include an object as a default value, it will be shared among all instances. Instead, define defaults as a function.
我有一个模型,其属性比默认属性多。我需要在 guest
更改时清除所有属性并设置回默认值,这样我就不会携带不必要的属性。
由于 change:guest
事件,清除所有属性并设置回默认值会导致无限循环。
如何删除除一个属性之外的所有属性?
当模型属性设置回默认值时,有没有办法不触发另一个更改事件?
或者删除默认值中未列出的任何内容?
这是我的模特
defaults: {
_id: 'id',
first_name: 'first_name',
last_name: 'last_name',
guest: true
}
我听'guest'改变事件
this.on('change:guest', this.reset);
更改事件调用 reset
来更新模型,显然这会导致无限循环。
reset: function() {
var new_defaults = _.clone(this.defaults);
this.clear({silent: true});
this.set(new_defaults);
}
I have made a reset
function that you can easily add to a base Backbone model. I go into more details about this solution into another answer.
它比简单的 .clear
followed by a .set
because it merges the 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
,这里使用 { 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
应该是一个返回对象的函数。
defaults: function() {
return {
arr: [],
nested: { prop: 'test' }
};
},
然后,使用_.result
to call the defaults: _.result(this, 'defaults')
like in my reset function. The Backbone documentation on defaults
有这个通知:
Remember that in JavaScript, objects are passed by reference, so if you include an object as a default value, it will be shared among all instances. Instead, define defaults as a function.