2

我正在扩展 Backbone 视图,例如:

var baseView = Backbone.View.extend({
    fruits : [],
    listFruits : function() {
        console.log(this.fruits);
    }
});

var firstView = baseView.extend({
    initialize : function() {
        this.fruits.push("apple");
    }
});

var secondView = baseView.extend({
    initialize : function() {
        this.fruits.push("pear");
    }
});


var firstViewInstance = new firstView(); // ["apple", "pear"]
var secondViewInstance = new secondView(); // ["apple", "pear"]

firstViewInstance.listFruits();
secondViewInstance.listFruits();

在我看来,firstViewInstance应该secondViewInstance是完全分开的,但它们显然是相关的。如何实现两个独立的视图对象,它们都继承自一个共同的基础,但共享数据?

编辑:根据下面的答案,我在http://jsfiddle.net/qZ7SU/有一个更新的小提琴,这似乎解决了这个问题。我仍然不完全清楚发生了什么,但我认为明确附加fruits[]this,将其创建为实例变量,而不是将其附加到原型。

4

2 回答 2

4

这是因为对原始fruits-property 的引用是被复制到子视图的那个。见下划线.jsextend

_.extend = function(obj) {
  each(slice.call(arguments, 1), function(source) {
    if (source) {
      for (var prop in source) {
        obj[prop] = source[prop];
      }
    }
  });
  return obj;
};

要从公共基础继承,但不共享数据,您需要在初始化函数中初始化非共享属性。

var baseView = Backbone.View.extend({
  initialize: function() {
    this._initializeBase();
  },

  _initializeBase: function() {
    this.fruits = [];
  },

  listFruits : function() {
    console.log(this.fruits);
  }
});

var firstView = baseView.extend({
  initialize : function() {
    this._initializeBase();
    this.fruits.push("apple");
  }
});

这样,属性将在初始化时添加到对象中,并且不会共享数据。

希望这可以帮助!

于 2013-04-12T09:53:25.367 回答
2

我写了一篇更详细的博客文章,但最简单的方法是提供一个自定义构造函数,确保fruits在每个子视图的原型上创建,而不是在baseView.prototype所有子视图继承的原型上创建。

var baseView = Backbone.View.extend({
  constructor: function() {
    this.fruits = [];
    Backbone.View.apply(this, arguments);
  },
  listFruits : function() {
    console.log(this.fruits);
  }
});

var firstView = baseView.extend({
    initialize : function() {
        this.fruits.push("apple");
    }
});

var secondView = baseView.extend({
    initialize : function() {
        this.fruits.push("pear");
    }
});


var firstViewInstance = new firstView(); // ["apple"]
var secondViewInstance = new secondView(); // ["pear"]
于 2013-04-15T18:53:59.773 回答