我有一个主干类:骨干类模型不继承默认
class BaseClass extends Backbone.Model
defaults:
first_name: "John"
class ExtendClass extends BaseClass
defaults:
last_name: "Doe"
然而,当我做一个new ExtendClass
,它没有first_name
。
我误解Backbone如何扩展?
我有一个主干类:骨干类模型不继承默认
class BaseClass extends Backbone.Model
defaults:
first_name: "John"
class ExtendClass extends BaseClass
defaults:
last_name: "Doe"
然而,当我做一个new ExtendClass
,它没有first_name
。
我误解Backbone如何扩展?
我想你是误解CoffeeScript如何扩展。当你说:
class A
p: ...
class B extends A
p: ...
的B::p
值完全隐藏A::p
,CoffeeScript的不会尝试将它们合并或链条他们或做什么特别的。
中的骨干模型defaults
可以是对象或函数,所以你可以使用的功能和CoffeeScript中的super
自己对它们合并:
class BaseClass extends Backbone.Model
defaults: ->
first_name: "John"
class ExtendClass extends BaseClass
defaults: ->
_(super).extend(last_name: "Doe")
这将使你在ExtendClass
默认值都first_name
和last_name
。
的extend()
帮手骨干,您可以扩展原型。在没有骨干网的普通的JavaScript扩展方法,我们可以建立原型连锁店如下面的例子:
function BaseClass(opts) {
// Here `this.defaults` will point to `BaseClass.prototype.defaults`
// when we create an instance of BaseClass.
//
// When we create an instance of ChildClass `this.defaults` will
// point to `ChildClass.prototype.defaults` if it exists, otherwise
// it will point to `BaseClass.prototype.defaults`.
this.attrs = _.extend({}, this.defaults, opts);
// Call `BaseClass.prototype.initialize` or `ChildClass.prototype.initialize`,
// depending on what instance we're creating.
this.initialize();
}
BaseClass.prototype.defaults = {
first_name: 'anonymous',
friend_count: 500
};
BaseClass.prototype.initialize = function() {
console.log('Hello ' + this.attrs.first_name);
};
function ChildClass(opts) {
// Let the base class set the `attrs` property
// and call the initialize() method.
BaseClass.call(this, opts);
}
// Set the prototype chain
ChildClass.prototype = Object.create(BaseClass.prototype);
// Create own `defaults` object, therefore overriding
// the one higher in the prototype chain.
ChildClass.prototype.defaults = {
last_name: 'backbone',
parent_name: 'Unknown'
};
ChildClass.prototype.initialize = function() {
// Do something...
};
从上面的例子可以看出,ChildClass设置它的原型自己的defaults
财产,因此ChildClass实例当一个对于defaults
的查询,JavaScript将在ChildClass原型对象中找到一个,并且不再查看。
这正是Backbone背景中发生的情况。 Backbone将寻找名为defaults
的属性,并将其与实例的属性合并,并且由于ChildClass有其自己的defaults
属性,因此Backbone将不会再进一步查看,也不会自动为您自动合并BaseClass默认值。
但是,在Backbone中,您可以将defaults
属性设置为函数,然后您可以手动访问BaseClass的默认值,以便将它们与ChildClass的默认值合并。这种手动布线是故意的,因为Backbone不希望假设任何有关您的对象层次结构(,在这种情况下您的型号为)。
在JavaScript代码是这样的:
var Note = Backbone.Model.extend({
defaults: {
title: 'Untitled',
message: 'Lorem ipsum dolor...'
},
initialize: function() { /* ... */ },
});
var PrivateNote = Note.extend({
defaults: function() {
var defaults = _.extend({}, { date: new Date() }, Note.prototype.defaults);
// You can also do this if you don't want to specify `Note` by its name:
// var defaults = _.extend({}, { date: new Date() }, this.constructor.__super__.defaults);
// `__super__` is specific to Backbone and in this case
// it gives you access to `Note.prototype`.
return defaults;
},
initialize: function() { /* ... */ },
});
现在我们得到了我们想要的:
var private = new PrivateNote();
private.toJSON();
//=> {date: Mon Feb 09 2015 00:57:14 GMT-0500 (EST), title: "Untitled", message: "Lorem ipsum dolor..."}
注意实例是不变的,我们所期望的:
var note = new Note()
note.toJSON();
//=> {title: "Untitled", message: "Lorem ipsum dolor..."}
这里是一个js2.coffee示例:Merge defaults with Parent defaults