Pergunta

So I am using views that are sidebars that have tabs in them, so I created a parent class SidebarView from which I extend two new classes. LeftSidebarView and RightSidebarView. here is the parent class:

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

Notice the "tabs: []" array. The two classes that extend from it have only initialize function in them that populates the 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;
});

and the other one is:

/*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;
});

In my main.js file I do this:

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

What happens is that the leftSideBarView which is an instance of LeftSidebarView and rightSidebarView an instance of RightSidebarView both have 3 members inside of this.tabs. It looks like. I still consider myself a javascript noob so I have got to ask if this is an expected behavior? Why does this happen? I looked at the documentation of _.extend and it says it returns a copy not a reference. So I'm kinda surprised by this happening.

edit: formulated the introduction a bit better and cleaned code a little.

Foi útil?

Solução

The tabs property are attached to the SidebarView.prototype which means that it is shared between RightSidebarView and LeftSidebarView instances. Everything you send as config options in extend method will override the base class prototype and is shared - like static properties in object oriented languages! That means that you will have to change the implementation to initialize tabs in initialize method like:

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

Outras dicas

I am assuming that you meant to declare tabs as a hash not an array since you are using property assignment further down the line. You can use an array but you would push elements into it rather than assigning properties.

The tabs property does not exist on your extended objects. It is defined further up the prototype chain on SidebarView. You can see in this fiddle, when you call rightSidebar.hasOwnProperty('tabs') and it returns 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); 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top