2012-02-23 161 views
6

我想为一个对象浏览器编写一个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({ 

    }); 

一如往常我不止在问候我所提供的代码片段的任何方面欢迎反馈。

谢谢 亚历

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

回答

4

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

但是这是我怎么看它 如果你有一个视图对象

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

,你必须把它扩展了backbone.View ......那么你确实有骨干的一切新的视图对象。视图,以及作为参数提供的额外选项。

如果你然后去创造第二个观点,扩展你的第一个 它会从你的第一个视图得到的一切,+它自己的演员

var mySecondView = myView.extend({ 
    foobar: "[email protected]" 
}); 

,如果你将创建第二个视图的一个实例并记录它的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-小提琴玩弄它可以在这里找到:从Backbone.View http://jsfiddle.net/saelfaer/uNBSW/

+0

嗨桑德,对不起我的问题是,没有足够的描述。我还创建了JS-Fiddle以更好地展示我的问题的核心。也许我应该从一开始就这样做。我的问题是,子类共享集合属性。 http://jsfiddle.net/JhZXh/3/ – 2012-02-23 02:11:27

+0

在任何情况下,只需将jsfiddle和描述添加到原始文章中,并不是每个人都可以在评论中找到它。我会看看它,看看我能不能找到一个更合适的答案。 – Sander 2012-02-23 07:09:01

3

继承不起作用,或者是相当复杂。

你应该创建一个共同的目标,其中每个视图将继承,即:

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) { /* ... */ }, 
}) 
+0

可以工作,但就我所知不是OP需要什么而言,他的问题是,他不是'otherFunction',而是定义一个属性,这是一个集合。并从这一观点延伸出来,两种观点都分享了收藏品的提法,即拥有自己的收藏品。这就是为什么他现在建议自己从初始化方法初始化它,而不是在视图本身上定义它。 – Sander 2012-02-24 11:09:14

+2

这不起作用,因为扩展会复制到ViewInterface,因此anotherView中也会存在另一个函数。 – pedroteixeira 2012-04-13 15:33:17

11

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

我相信正确的方法来实现我正在寻找的是将属性的初始化移动到由骨干视图提供的初始化方法。这样,他们将被初始化

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/