我知道有人将标志着这是重复的,但我经历了几乎所有与此相关的主题的帖子去了,这不是我期待的。所以这是自上周以来我的想法。骨干观的继承
我一直负责创建视图的原子设计。将会有一个核心基础视图,然后另一个视图将扩展它,等等。元素 - >面板 - >窗口,元素 - >面板 - >弹出等。随着Backbone.View.extend我可以简单地做到像
var BaseView = Backbone.View.extend({
initialize : function(options) {
this.$el.attr('cid', this.cid);
this.base = options.base || arguments[0]['base'];
this.parent = options.parent || arguments[0]['parent'];
this.children = [];
if(typeof this.template !== 'undefined') {
if (typeof this.template=='function') {
// do nothing. template is already a underscore template and will be parsed when first call;
}
else if (typeof this.template=='string' && this.template.substr(0,1)=='#') {
if ($(this.template).length >0 ) {
this.template = _.template($(this.template).html());
}
else {
console.warn('Template element ' + this.template + 'could not be located in DOM.');
}
}
else {
this.template = _.template(this.template);
}
}
else {
this.template = _.template('<span></span>');
}
if (typeof this.parent!=='undefined' && this.parent) {
this.parent.add.apply(this.parent, [this]);
}
},
add: function(child){
this.children.push(child);
},
getChildren : function(){
return this.children;
},
clean: function(){
this.$el.empty();
},
close: function() {
BaseView.prototype.clear.apply(this, [true]);
this.undelegateEvents();
this.unbind();
this.stopListening();
this.remove();
},
clear: function(){
if (this.children.length > 0) {
empty = empty || false;
_.each(this.getChildren(), function (child, index) {
Baseview.prototype.close.apply(child);
});
this.children = [];
if (empty) {
this.$el.empty();
}
}
return this;
}
})
然后,如果我尝试使用它作为
var Layout = new BaseView.extend({
el: '#someElement',
template : '#sometemplate',
initialize : function(){
this.childView = new ChildView({parent: this, base: this, collection: someCollection});
return this;
},
render: function(){
this.clean().$el.append(this.template({}));
this.$('.content').append(this.childView.render().$el);
return this;
},
});
var ChildView = BaseView.extend({
tagName : 'div',
template : '#childTemplate',
initialize : function(){
return this;
},
render: function(){
var self = this;
this.clean().$el.append(this.template({}));
this.$list = this.$('ul');
_.each(this.collection.models, function(model){
var grandChildView = new GrandChildView({parent: self, base: self.base, model: model});
self.$list.append(grandChildView.render().$el);
})
return this;
}
});
var GrandChildView = BaseView.extend({
tagName : 'li',
template : '#grandChildTemplate',
initialize : function(){
return this;
},
render: function(){
this.clean().$el(this.template(this.model.toJSON()));
return this;
}
});
$(function(){
new Layout();
})
不起作用,因为不是在BaseView上运行初始化,Backbone要求首先启动,而this.template和其他所有未定义。
然后我试图与constructor
来取代它,而不是初始化的基本视角。但后来我结束了this.$el
未定义的错误,因为Backbone.View.constructor没有被调用却又如此没有this.$el
尚未正在由_ensureElement
因此创造了一些研究,我发现的唯一的事情是用
Backbone.View.prototype.constructor.apply(this,[options]);
但是,这也导致类似的问题,在Backbone.View结束,对于this.initialize.apply调用(这一点,[选项]),然后进入到子对象初始化代替。所以我被卡住了,无法将这个包裹在我的头上。
我也知道,我可以从childview拨打父母的初始化函数,但由于有很多延伸彼此的子视图这是不可取的。这就是我通过父对象将后面的对象附加到它的子对象的原因。
我想要完成的是创建一个包装扩展对象,我可以稍后扩展另一个对象,但同时它应该在原始基础视图上运行一些常见任务,附加其他原型方法,然后调用调用方初始化。
所以伪
var BaseView {
extend Backbone view with the passed arguments,
check for base, parent arguments and set them
check for template option, if exists then get the element, create template function and replace with the string one,
if there is parent view passed, then attach yourself to children of parent
call your own initialize method,
return
}
这里有不同的方式[使得与骨干网的良好基础类(http://stackoverflow.com/a/40982556/1218980)。看起来很多责任不在正确的课堂上处理。我从不需要将父类传递给它的孩子,对于父母来说,处理孩子和倾听事件总是会更好,所以孩子班可以保持专注和可重用。 –
谢谢。是的,我同意你提到的亲子关系。但在原子设计概念。孩子继承可能有其他的东西。想想像ExtJs这样的东西。原始基类是Ext.Element,它创建一个空的div元素,id等属性。然后Ext.Panel扩展了Ext.Element,并且使用了Ext.Elements功能,添加了面板头,主体,设计等,然后Ext.Window使用几乎相同的功能扩展了Ext.Panel,但它们都是浮动的,它们都有初始化方法并被调用以达到主要元素。 –
但是在使用调用者的配置初始化Ext.Window之前,Ext.Element首先被创建。我试图完成的是类似的。 BaseView应该是一个处理大部分预初始化功能的包装器内容设置,然后在创建新对象时,它将自己附加到父对象上,所以当父对象被销毁时,所有的孩子都可以使用它。否则,当父母被移除时,孩子将成为孤儿。 –