【问题标题】:Backbone View Inheritance骨干视图继承
【发布时间】:2012-02-23 01:24:02
【问题描述】:

我正在尝试为对象浏览器编写 Backbone 视图,该视图旨在在具有不同对象类型和略有不同操作的多个地方实现。

我尝试过简单地在浏览器中扩展主干视图,然后在我的实现中扩展浏览器,但这给我留下了一些共享的属性。这是一个不受欢迎的效果,因为每次创建浏览器时都会将数据附加到所有实现中。

有人可以阐明解决此问题的方法或替代解决方案吗?

以下是一些代码示例,可让您更好地了解当前的情况:

    var BrowserView = Backbone.View;

    _.extend(BrowserView.prototype, Backbone.View.prototype, {
        className: 'browser',

        collections: [],

        events: {

        },

        _events:{

        },

            initialize: function () {
            this._initialize();
        },

        render: function () {
            this._render();
        },

        _initialize: function () {
            this.container = $( this.make('div', {class: 'container'} ) );

            this.$el.append(this.container);

            if ( this.options.collections ) {
                this.collections = [];

                _.each(this.options.collections, this.add, this);
            }

            _.extend(this.events, this._events);

            this.delegateEvents();
        },

        _render: function () {
            this.container.empty();

            _.each(this.collections, function (view) {
                this.container.append(view.el);

                view.render();
            }, this);
        }
    });

    BrowserView.extend = Backbone.View.extend;

    var ContactBrowserView = BrowserView.extend({

    });

编辑 我的问题是子类共享集合属性。这是我自己的解决方案的一个示例,它通过继承的方法初始化集合属性。 jsfiddle.net/JhZXh/3

【问题讨论】:

    标签: javascript class view backbone.js prototype


    【解决方案1】:

    我想我已经找到了自己问题的答案。

    我相信实现我正在寻找的正确方法是将属性的初始化移动到 Backbone 视图提供的初始化方法中。这样他们就被初始化了

    var BrowserView = Backbone.View.extend({
        initialize: function () {
            this.collections = [];
        }
    });
    
    var FileBrowserView = BrowserView.extend({
        initialize: function () {
            BrowserView.prototype.initialize.apply(this);
            
            this.collections.push({name: 'Example Collection' + Math.rand()});
        }
    });
    
    
    var FileBrowserInstance1 = new FileBrowserView;
    console.log(FileBrowserInstance1.collections);
    
    var FileBrowserInstance2 = new FileBrowserView;
    console.log(FileBrowserInstance2.collections);
    

    http://jsfiddle.net/yssAT/2/

    【讨论】:

      【解决方案2】:

      很难看出你的目标到底是什么。

      但这就是我的看法 如果你有一个视图对象

      var myView = Backbone.View.extend({
          foo: "bar"
      });
      

      你让它扩展了主干。视图...然后你实际上有一个新的视图对象,其中包含主干视图的所有内容,以及你作为参数提供的额外选项。

      如果你接着创建第二个视图,它会扩展你的第一个视图 它会从你的第一视角得到一切,+它自己的附加功能

      var mySecondView = myView.extend({
          foobar: "f00b@r"
      });
      

      如果您要创建第二个视图的实例并记录它的 foo 属性,它仍将保持 "bar" 作为值

      var mySecondViewInstance = new mySecondView();
      console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo);
      console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar);
      

      如果我创建第一个视图的新实例,并将 foo 更改为 "changed-foo" foomySecondViewInstance 上的日志仍然是 "bar"

      var myViewInstance = new myView();
      myViewInstance.foo = "changed-foo";
      console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo);
      console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar);
      

      可以在这里找到一个 JS-Fiddle 来玩它: http://jsfiddle.net/saelfaer/uNBSW/

      【讨论】:

      • 您好 Sander,抱歉我的问题描述性不够。我还创建了一个 JS-Fiddle 来更好地展示我的问题的核心。也许我应该从一开始就这样做。我的问题是子类共享集合属性。 jsfiddle.net/JhZXh/3
      • 无论如何,只要将那个jsfiddle和描述添加到您的原始帖子中,并不是每个人都会在评论中找到它。我会看看它,看看我是否能想出一个更合适的答案。
      【解决方案3】:

      Backbone.View 继承不起作用,或者非常复杂。

      您应该创建一个通用对象,您的每个视图都将从该对象继承,即:

      var ViewInterface = {
        events        : { /* ... */ },
        initialize    : function (options) { /* ... */ },
        otherFunction : function (options) { /* ... */ },
      }
      

      您的每个视图都将从该对象扩展:

      var BrowserView = Backbone.View.extend(_.extend(ViewInterface, {
        anotherFunction : function (options) { /* ... */ },
      })
      
      var AnotherView = Backbone.View.extend(_.extend(ViewInterface, {
        yetAnotherFunction : function (options) { /* ... */ },
      })
      

      【讨论】:

      • 那会起作用,但据我所知,OP 需要什么,他的问题是,他定义了一个属性,而不是otherFunction,它是一个集合。通过从这一观点延伸,两种观点都共享对收藏的引用,而不是拥有自己的收藏。这就是为什么他现在建议自己,从 initialize 方法初始化它,而不是在视图本身上定义它。
      • 这实际上不起作用,因为extend会复制到ViewInterface,因此anotherFunction也会存在于AnotherView中。
      【解决方案4】:

      这个要点显示了一个更好的选择: https://gist.github.com/2287018

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-05
        • 2017-10-04
        • 1970-01-01
        • 2013-06-30
        • 2013-01-14
        • 1970-01-01
        • 2015-08-22
        • 2012-03-21
        相关资源
        最近更新 更多