0

我定义了一个主干视图

Views.BaseView = Backbone.View.extend({
   viewState : new Backbone.Model(),
   initialize: function(){
       this.listenTo(this.viewState, "change:stateType", this.onAlertType)
  }
}

我有扩展 BaseView 的 GlobalView,它允许我显示和管理我的 ItemView。ItemView 也扩展了 BaseView。

我的问题是,如果我在 ItemView 级别更改 viewState.stateType :

MyItemView.viewState.set('stateType', 1)

GlobalView 首先通知 ItemView 的 viewState 属性的变化。

我的 GlobalView 没有得到任何特定的“listenTo”,我定义的唯一“listenTo”是 BaseView 级别的。

为什么 globalView 会收到有关 ItemView 上定义的 viewState 对象更改的通知?有没有人看到我做错了什么?这是一个已知的错误吗?

4

1 回答 1

1

当您使用 定义 Backbone 对象(例如View.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

当您将属性设置为可变对象(例如ObjectArray或类似对象)时,就会出现问题。当您更改该对象而不重新分配属性时,这会更改所有实例上的该属性值。

在您的情况下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)
  }
}
于 2013-02-11T11:07:10.720 回答