Расширение представлений в backbonejs с помощью requirejs

Итак, я использую представления, представляющие собой боковые панели с вкладками, поэтому я создал родительский класс 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, имеют 3 члена внутри this.tabs. Это выглядит как. Я все еще считаю себя новичком в javascript, поэтому я должен спросить, является ли это ожидаемым поведением? Почему это происходит? Я просмотрел документацию _.extend, и там сказано, что она возвращает копию, а не ссылку. Так что я немного удивлен происходящему.

edit: немного лучше сформулировал введение и немного почистил код.


person aledujke    schedule 25.04.2013    source источник
comment
Это немного сложнее, чем просто вызвать функцию extend. Вот пост, который направит вас на правильный путь. stackoverflow.com/questions/7735133/   -  person Scott Puleo    schedule 25.04.2013
comment
Моя проблема не в том, что родительская функция не вызывается из-за того, что я их переопределяю. У меня проблема в том, что leftSidebarView.tabs === rightSidebarView.tabs   -  person aledujke    schedule 25.04.2013


Ответы (2)


Свойство tabs прикреплено к SidebarView.prototype, что означает, что оно совместно используется экземплярами RightSidebarView и LeftSidebarView. Все, что вы отправляете в качестве параметров конфигурации в методе расширения, переопределяет прототип базового класса и является общим — как статические свойства в объектно-ориентированных языках! Это означает, что вам придется изменить реализацию для инициализации вкладок в методе инициализации, например:

SidebarView:
initialize : function() {
    this.tabs = [];
}
RightSidebarView:
initialize: function() {
    RighitSidebarView.__super__.initialize.apply(this, arguments);
    // additinal initialization stuff...
}
person Aleksandar Mirilovic    schedule 25.04.2013
comment
Спасибо. Я приму этот ответ, поскольку это более универсальное решение, которое создаст меньше беспорядка в коде, если я объявлю более одной нестатической переменной. - person aledujke; 26.04.2013

Я предполагаю, что вы хотели объявить вкладки как хэш, а не как массив, поскольку вы используете присваивание свойств дальше по строке. Можно использовать массив, но вы будете вставлять в него элементы, а не назначать свойства.

Свойство 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); 
person Scott Puleo    schedule 25.04.2013