使用requirejs扩展backbonejs中的视图

时间:2013-04-25 18:26:44

标签: backbone.js requirejs underscore.js amd extending-classes

所以我使用的视图是带有标签的侧边栏,因此我创建了一个父类SidebarView,我从中扩展了两个新类。 LeftSidebarView和RightSidebarView。这是父类:

define([
  'jquery',
  'underscore',
  'backbone',
  'eventbus'
], function ($, _, Backbone, eventBus) {
  'use strict';
  var SidebarView = Backbone.View.extend({
    tabs: [],
    isHidden: true,
    alignment: '',
    el : '',
    templateId: '',
    milliseconds: 300,

注意“tabs:[]”数组。从它扩展的两个类只有初始化函数,用于填充选项卡:

define([
  'jquery',
  'underscore',
  'backbone',
  'views/sidebar',
  'eventbus',
  'views/search'
], function ($, _, Backbone, SidebarView, eventBus, SearchView) {
  'use strict';
  var RightSidebarView = SidebarView.extend({
    alignment: 'right',
    el: "#rightSidebar",
    templateId: '#sidebarTemplate',

    initialize : function() {
      this.tabs['search'] = new SearchView({model: this.model});
    }
  });
  return RightSidebarView;
});

另一个是:

/*global define*/
define([
  'jquery',
  'underscore',
  'backbone',
  'views/sidebar',
  'views/listings',
  'views/listingDetails',
  'eventbus'
], function ($, _, Backbone, SidebarView, ListingsView, ListingDetailsView, eventBus) {
  'use strict';
  var LeftSidebarView = SidebarView.extend({
    alignment: 'left',
    el: "#leftSidebar",
    templateId: '#sidebarTemplate',

    initialize : function() {
      this.tabs['listings'] = new ListingsView({collection: this.collection);
      this.tabs['listingDetails'] = new ListingDetailsView();
    }
  });

  return LeftSidebarView;
});

在我的main.js文件中,我这样做:

var leftSidebarView = new LeftSidebarView({collection:listings});
var rightSidebarView = new RightSidebarView({model: searchModel});

leftSideBarView是一个LeftSidebarView实例,rightSidebarView是一个RightSidebarView实例,它们在this.tabs中都有3个成员。看起来像。我仍然认为自己是一个javascript noob,所以我不得不问这是否是一个预期的行为?为什么会这样?我查看了_.extend的文档,它说它返回的是副本而不是引用。所以我对这种情况感到惊讶。

编辑:稍微改进了一下代码,然后清理了一些代码。

2 个答案:

答案 0 :(得分:3)

tabs属性附加到SidebarView.prototype,这意味着它在RightSidebarView和LeftSidebarView实例之间共享。您在extend方法中作为配置选项发送的所有内容都将覆盖基类原型并且是共享的 - 就像面向对象语言中的静态属性一样!这意味着您必须更改实现以初始化初始化方法中的选项卡,如:

SidebarView:
initialize : function() {
    this.tabs = [];
}
RightSidebarView:
initialize: function() {
    RighitSidebarView.__super__.initialize.apply(this, arguments);
    // additinal initialization stuff...
}

答案 1 :(得分:2)

我假设您打算将制表符声明为散列而不是数组,因为您正在使用属性分配。 您可以使用数组但是您可以将元素推入其中而不是分配属性。

您的扩展对象上不存在tabs属性。它在SidebarView上的原型链中进一步定义。你可以在这个小提琴中看到,当你调用rightSidebar.hasOwnProperty('tabs')并返回false时。

http://jsfiddle.net/puleos/yAMR2/

var SidebarView = Backbone.View.extend({
    tabs: {},
    isHidden: true,
    alignment: '',
    el : '',
    templateId: '',
    milliseconds: 300
});

var RightSidebarView = SidebarView.extend({
    alignment: 'right',
    el: "#rightSidebar",
    templateId: '#sidebarTemplate',

    initialize : function() {  
      this.tabs['search'] = {type: "search"};
    }
  });

var LeftSidebarView = SidebarView.extend({
    alignment: 'left',
    el: "#leftSidebar",
    templateId: '#sidebarTemplate',

    initialize : function() {
      this.tabs['listings'] =  {type: "listings"};
      this.tabs['listingDetails'] = {type: "listing details"};
    }
});

var rightSidebar = new RightSidebarView();
var leftSidebar = new LeftSidebarView();

console.log(rightSidebar.hasOwnProperty('tabs'));  // false
console.log(rightSidebar.tabs);