我有简单的视图,显示对话框。
Backbone.View.prototype.completeRemove = function(){
this.undelegateEvents();
this.remove();
delete this.$el;
delete this.el;
console.log('completely removed')
}
MdApp.dialogBox = Backbone.View.extend({
defaults: {
text: __('No text provided'),
buttonText: __('Ok'),
callback: function(){
return null;
},
el: $('#app-panel'),
type: 'error',
cancellable: false,
cancelText: __('No'),
picture: pic('default')
},
el: '<div class="dialog-box">',
template: _.template($('#dialog-box-template').html()),
events: {
'click .confirm' : 'confirm',
'click .cancel' : 'cancel'
},
initialize: function(){
this.model = _.extend(this.defaults, this.model);
this.render();
},
render: function(){
var model = this.model;
this.$el.html(this.template(model));
model.el.append(this.el);
},
confirm: function(){
var model = this.model;
var view = this;
this.completeRemove();
model.callback();
},
cancel: function(){
this.completeRemove();
}
});
它有自己的默认值。每次我初始化新对话框时,它的值在每次对话框调用之间都会持续存在。例如,当我第一次调用对话框时:
new MdApp.dialogBox({model:{
text: __('Do you really wanna delete this?'),
buttonText: __('Unfortunately yes'),
callback: function(){
//some callback
},
cancellable: true,
cancelText: __('No'),
picture: pic('confirm delete')
}});
之后,我正在调用另一个没有cancellable
属性的对话框,因此它应该使用默认值(false
),但它仍然是正确的。这适用于所有其他财产。为什么会这样?
答案 0 :(得分:2)
来自fine manual:
延伸
_.extend(destination, *sources)
将来源对象中的所有属性复制到目标对象,然后返回目标对象。
这意味着_.extend(o, ...)
会修改o
。所以当你这样做时:
this.model = _.extend(this.defaults, this.model);
你实际上是这样做的:
for(k in this.model)
this.defaults[k] = this.model[k];
this.model = this.defaults;
defaults
已附加到原型中,因此您实际上正在更改defaults
的每个实例共享的MdApp.dialogBox
。这就是为什么你最终会遇到粘性属性:你将所有不同的this.model
合并到视图原型的defaults
上。
你可以这样做:
// Merge into an empty object to avoid altering this.defaults
this.model = _.extend({}, this.defaults, this.model);
或者您可以使用_.defaults
代替_.extend
:
默认
_.defaults(object, *defaults)
使用默认值对象中的值填充对象中的空和未定义属性,然后返回对象。一旦财产被填满,进一步的违约将无效。
所以你可以这样做:
_(this.model).defaults(this.defaults);
这将改变this.model
就地,因此您的视图将假设它完全拥有this.model
并且没有任何外部引用该对象。