Search code examples
javascriptdesign-patternsbackbone.jsrequirejs

Separate Backbone View functions into separate files


I have a Backbone View.

To organize better the code of it, I would to prefer to separate some functions of it into a separate file.

So, I would like to maintains the structure but simply I need to separate the functions into different files:

- MyView
   - functions A -> file A;
   - functions B -> file B;

I would like to use the view in the same current mode. So I need to call the functions 'A' on my view: myViewInstance.functionA_1()

What is the correct way/pattern to implement this?

I use also RequireJS.


Solution

  • You can use the Mixin pattern. Divide the prototype of MyView to the main part and to other parts, put them to separate modules, make the main module depend on them and merge the parts together.

    Add prototype members from the main part to the declaration of MyView as usual:

    var MyView = Backbone.View.extend({
      method: function () {
        this.otherMethod();
      }
    });
    

    Put the other parts of the prototype to separate modules and export them as object literals:

    var prototypePart = {
      otherMethod: function () {}
    };
    

    Make the main module depend on them and merge the prototype from all imported parts either by Object.assign or by _.extend:

    // Merging the prototype with ES6.
    Object.assign(MyView.prototype, prototypePart);
    // Merging the prototype with Underscore.js.
    _.extend(MyView.prototype, prototypePart);
    

    You will get MyView as if declared "in one piece":

    var MyView = Backbone.View.extend({
      method: function () {
        this.otherMethod();
      },
      otherMethod: function () {}
    });
    

    For example, myview.js exports MyView. It depends on two other modules in order to import other parts of the MyView prototype from them:

    define([
      'underscore', 'backbone', './myview-a', './myview-b'
    ], function (_, Backbone, myViewA, myViewB) {
      var MyView = Backbone.View.extend({
        // ...prototype members from this module
        initialize: function () {
          this.fromModuleA();
        }
      });
      // Add prototype members imported from other modules
      _.extend(MyView.prototype, myViewA);
      _.extend(MyView.prototype, myViewB);
      return MyView;
    });
    

    myview-a.js exports an object with a group of additional MyView prototype members:

    define(function () {
      var myViewA = {
        // ...prototype members from this module
        fromModuleA: function () {
          this.fromModuleB();
        }
      };
      return myViewA;
    });
    

    myview-b.js exports an object with another group of MyView prototype members:

    define(function () {
      var myViewB = {
        // ...prototype members from this module
        fromModuleB: function () {}
      };
      return myViewB;
    });