我定义了骨干视图
Views.BaseView = Backbone.View.extend({
viewState : new Backbone.Model(),
initialize: function(){
this.listenTo(this.viewState, "change:stateType", this.onAlertType)
}
}
我有扩展BaseView的GlobalView,这允许我显示和管理我的ItemViews。 ItemView也扩展了BaseView。
我的问题是,如果我在ItemView级别更改viewState.stateType:
MyItemView.viewState.set('stateType', 1)
首先通知GlobalView有关ItemView的viewState属性的更改。
我的GlobalView没有得到任何特定的'listenTo',我定义的唯一'listenTo'是BaseView级别的那个。
为什么要通知globalView有关ItemView上viewState对象的更改? 有人看到我做错了吗?这是一个已知的错误吗?
答案 0 :(得分:1)
使用View
在Backbone对象(例如.extend
)上定义属性时,该属性将附加到对象的原型。这意味着该对象的所有实例共享相同的属性值。
这对方法非常有意义,因为您不希望为对象的每个实例的每个方法创建一个新的函数实例。它对不可变值类型属性也相对无害,因为原始值未被修改,并且当您使用另一个值重新分配属性时,会在该实例上创建一个新属性,并隐藏原型属性而不修改它:
var SomeView = BaseView.extend({
foo:'foo'
});
var view1 = new SomeView();
var view2 = new SomeView();
view1.foo = 'bar';
console.log(view1.foo, view2.foo); // -> bar, foo
当您将属性设置为可变对象(例如Object
,Array
或类似对象)时,会出现问题。如果在不重新分配属性的情况下更改该对象,则会更改所有实例上的该属性值。
在您的情况下,所有视图的viewState
属性都指向同一个模型实例,因此:
var view1 = new SomeViewThatExtendsBaseView();
view1.viewState.set('stateType', 1);
var view2 = new SomeOtherViewThatAlsoExtendsBaseView();
console.log(view2.viewState.get('stateType')); // -> 1
要使用Backbone声明实例属性,您应该使用initialize
方法创建它们:
Views.BaseView = Backbone.View.extend({
initialize: function() {
this.viewState = new Backbone.Model();
this.listenTo(this.viewState, "change:stateType", this.onAlertType)
}
}