Javascript 扩展主干。视图

Javascript 扩展主干。视图,javascript,class,backbone.js,prototype,Javascript,Class,Backbone.js,Prototype,我正在努力扩展我的脊梁骨。查看类。 最初,我想到了创建自己的接口来简化删除ChildView所需的代码量 基本上,一个数组和一些方法可以迭代数组中的每个视图,并为每个视图调用remove。这在列表和类似的东西上特别有用 然后我尝试了类似的方法,发现从类创建的对象在其属性上共享同一个实例 Backbone.SuperView = Backbone.View.extend({ childViews: ['global'] }) var App_View = Backbone.SuperVie

我正在努力扩展我的脊梁骨。查看类。 最初,我想到了创建自己的接口来简化删除ChildView所需的代码量

基本上,一个数组和一些方法可以迭代数组中的每个视图,并为每个视图调用remove。这在列表和类似的东西上特别有用

然后我尝试了类似的方法,发现从类创建的对象在其属性上共享同一个实例

Backbone.SuperView = Backbone.View.extend({
  childViews: ['global']
})


var App_View = Backbone.SuperView.extend({
   initialize: function(options){
       this.childViews.push(options.viewName);
console.log('app_View =>' + this.childViews);
   }
})

var App2_View = Backbone.SuperView.extend({
   initialize: function(options){
       this.childViews.push(options.viewName);
console.log('app2_View =>' + this.childViews);
   }
})

new App_View({viewName: 'a'});
new App2_View({viewName: 'b'});
这将产生:

app_View =>  global ,a 
app2_View => global ,a ,b
我不希望在我从Backbone.SuperView创建的所有对象中都有相同的childview实例!就像你可以想象的那样,我假装在从该类创建的所有对象中都有一个数组childview,但我有不同的内存实例,所以每个视图都有自己的childview

然后我提出了以下概念,但我仍然认为这不是正确的做事方式:

我的SUPERVIEW课程

我的HTML

我的手稿

这感觉不对,我正在寻找一种更为坚实的解决方案。 我真的必须在每个视图中调用初始值设定项吗

上述代码的工作原理如下:

运行脚本将呈现一个包含3个项目和一个标题的列表

header_视图使用我自己创建的方法将事件绑定到视图外部的DOM元素

它将dom元素插入到数组中,稍后,当元素被销毁时,事件也会从该全局元素中分离,以防止内存和事件问题

在上述情况下,仅在header_视图中单击将从_BindeElements输出有界元素,因为InSide header_视图初始化我称之为.setEvent$el,“eventName”,回调


难道你不想这么说吗;在您的Superview中初始化?或者做这个的东西。儿童视图。推。。。如果阵列不存在,则可以创建阵列。我想我可以将SuperView设置为初始化。问题是我必须将Backbone.SuperView.prototype.initialize.callthis调用到从SuperView扩展的其他每个视图中,以使其工作。对我来说,就是感觉不对劲是的,链接在JavaScript中有点难看。但是为什么不在第一次访问时创建this.childViews数组呢?你不想让子类直接干扰ChildView,对吧?
;(function($, _ , Backbone) {
   'use strict';

   Backbone.SuperView = Backbone.View.extend({
      initialize: function(){
         this._views = {};
         this._listViews = [];
         this._bindedElements = [];

         _.extend(this,
            {
            _destoryAllViews: function(){
               this._removeListViews();
               this._removeViews();
               this.remove();
            },
            // destroy a view atual e as subviews e listviews
            destroy: function(options){
               options = options || {};
               var defaults = {timeout : 200};
               if (_.isEmpty(options)){
                  options = defaults;

                  setTimeout($.proxy(function(){
                     this._destoryAllViews();
                     this._cleanExternalEventBinds();
                  },this), options.timeout );
               } else {
                  this._destoryAllViews();
                  this._cleanExternalEventBinds();
               }
            },
            addListView: function(view){
               this._listViews.push(view);
            },
            // manual view cleaner
            emptyListView: function(destroy){
                this._removeListViews();
            },
            /*
               views with same keys are destroyed and then assigned
            */
            set: function(key, view, options){
               options = options || {};
               var destroy = ('destroy' in options ) ? options.destroy : true;

               if (key in this._views){
                  this._views[key].view.destroy();
               }

               this._views[key] = { 'view': view, 'destroy':  destroy };

               return view;
            },
            get: function(key){
               return this._views[key].view;
            },
            _removeViews: function(){
               _.each( this._views, function( viewSettings ){
                  if (viewSettings.destroy){
                     if (viewSettings.view.destroy){
                        viewSettings.view.destroy();
                     }
                  }
               });
            },
            _removeListViews: function(){
               _.each( this._listViews, function( view ){
                  if (view.destroy){
                     view.destroy();
                  }
               });
            },
            setEvent: function(el, eventName, callback){
               var $el = $(el),
                  callback = (_.isFunction(callback)) ? callback : this[callback];

                  $el.bind(eventName + '.' + this.cid, callback);

               this._bindedElements.push(el);
            },
            _cleanExternalEventBinds: function(){
               var _that = this;
               _.each(this._bindedElements, function(el){
                  el.off('.' + _that.cid );
               });
            }

         });

      }
   });


   //_.extend(Backbone.SuperView.prototype, )


   return Backbone;

})($, _ , Backbone);
<a href="#" class="my-btn">My-btn</a>
<div class="app-placeholder"></div>
var c = Backbone.Collection.extend({});

        var C = new c([{
            name: 'Frank',
            age: 12
        },
        {
            name: 'Maria',
            age: 19
        },
        {
            name: 'Richard',
            age: 20
        }])

        var header_View = Backbone.SuperView.extend({
            events: {
                'click': 'log'
            },
            initialize: function(){
                Backbone.SuperView.prototype.initialize.call(this);
                this.$mybtn = $('.my-btn');
                this.setEvent(this.$mybtn, 'click', function(e){
                    e.preventDefault();
                    alert('hello');
                });
                this.setEvent(this.$mybtn, 'click', 'innerHello')
                // this.setEvent(this.$mybtn, 'click', 'log')
                this.$el.append('<h1>My Header</h1>')
                return this;
            },
            innerHello: function(e){
                // e.preventDefault();
                alert('hello 2');
            },
            log: function(){
                console.log(this._bindedElements);
            }
        });

        var item = Backbone.SuperView.extend({
            template: _.template('<%= age %>||<%=name%>'),
            events: {
                'click': 'log'
            },
            initialize: function(options){
                Backbone.SuperView.prototype.initialize.call(this);
                this.model = options.model;
                this.render();
            },
            render: function(){
                this.$el.html('').append(this.template(this.model.toJSON()))
            },
            log: function(){
                console.log(this._bindedElements);
            }
        })

        var b = Backbone.SuperView.extend({
            initialize: function(){
                Backbone.SuperView.prototype.initialize.call(this);
                this.set('myView', new header_View());
                this.$el.html( '' ).append( this.get('myView').el );
                this.collection = C;
                this.render();
            },
            render: function(){
                this.emptyListView();
                this.addAll();
            },
            addAll: function(){
                this.collection.forEach(function(model){
                    var _item = new item({model:model});
                    this.addListView(  _item );
                    this.$el.append( _item.el );
                },this)
            }
        })

        var m = Backbone.View.extend({
            initialize: function(){

            },
        })

        var B = new b();
        $('.app-placeholder').append(B.el);