我正在扩展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
,将其创建为实例变量,而不是将其附加到原型。
答案 0 :(得分:4)
这是因为对原始fruits
- 属性的引用是被复制到子视图的属性。见underscore.js extend
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
}
});
return obj;
};
要从公共基础继承但不共享数据,您需要初始化initialize-function中的not-shared属性。
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");
}
});
这样,属性将在初始化时添加到对象中,并且不会共享数据。
希望这有帮助!
答案 1 :(得分:2)
我写了一篇关于此问题的更详细的blog post,但最简单的方法是提供一个自定义构造函数,确保在每个子视图的原型上创建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"]