Search code examples
inheritancebackbone.jsrequirejs

Backbone + RequireJS Object Inheritance


I have an issue using Backbone with RequireJS.

BaseListView.js

define(['backgrid',
  'backbone',
  'underscore', etc.], function (
    Backgrid,
    Backbone,
    _) {
  
  return Backbone.View.extend({
    initialize: function () {
      if(needDeleteCell) {
        this.addDeleteCell();
      }
      this.render();
    },

    addDeleteCell: function () {
      var ListViewDeleteCell = DeleteCell.extend({
        defaults: {
          successMsg: this.attributes.deleteSuccessMsg,
          failureMsg: this.attributes.deleteFailureMsg
        }
      });
      this.columns.push({
        name: "delete",
        label: "",
        editable: false,
        cell: ListViewDeleteCell
      }); 
    }
  });
});

ChildView.js

define(['i18next', './common/BaseListView'], function (i18n, BaseListView) {
  'use strict';

  return BaseListView.extend({
    columns: [{
      name: "_id",
      label: i18n.t('app.operationForm.id'),
      editable: false,
      cell: "string",
      renderable: false
    }, {
        name: "name",
        label: i18n.t('app.operationForm.nameLabel'),
        editable: false,
        cell: "string"
      }]
  });
});

Now if I want to use multiple instances of the child view, I have multiple "delete" columns (due to the columns.push() in the BaseListView) like if the columns attribute of the parent is a singleton instance.

In this case, ChildView is not the only Class extending the BaseListView

What is the proper way of doing this with Bacbkone + RequireJS?

Thank you.

Edit: this is the same issue as: Switching between singleton and prototype scope using RequireJS but I'd like to avoid the factory solution.


Solution

  • In Your case ChildView.columns is prototype scope. Every instances has the same columns.

    You may init columns in initialize function:

    define(['i18next', './common/BaseListView'], function (i18n, BaseListView) {
      'use strict';
    
      return BaseListView.extend({
        initialize: function () {
          this.columns = [{
            name: "_id",
            label: i18n.t('app.operationForm.id'),
            editable: false,
            cell: "string",
            renderable: false
          }, {
            name: "name",
            label: i18n.t('app.operationForm.nameLabel'),
            editable: false,
            cell: "string"
          }];
          BaseListView.prototype.initialize.call(this);
        });
      }
    });