Brian
Brian

Reputation: 7654

Extending Marionette.Application with module definitions

I've been writing an application of mine using Marionette, but I feel a bit confused that application extensions are failing.

There seems to be no way to do this sort of thing in MarionetteJS:

var SuperApplication = Backbone.Marionette.Application.extend({
    'modules': {
        'foo': function (module, app) {
            // module definition
        },
        'bar': function (module, app) {
            // module definition
        }
    }
});

var app = new SuperApplication();

While I have been developing, it has become important to occasionally create a new Application instance and call .module numerous times before the application object becomes useful. It negatively affects testing reliability of each Application object created, because there are no guarantees that they are of the same prototype.

The following method, ugly as it is, cannot properly attach a module definition to an Application as a prototype:

SecondApplication = Backbone.Marionette.Application.extend({
    'foo': function () {
        var args = slice(arguments);
        args.unshift(this);
        args.push(function (module, app) {
            // module definition
        });
        return Backbone.Marionette.Module.create.apply(
            Backbone.Marionette.Module, args);
    }
});

Am I supposed to do this some other way?

Upvotes: 1

Views: 1415

Answers (1)

Chris Camaratta
Chris Camaratta

Reputation: 2769

EDIT: Marionette modules are now deprecated and will be removed in the next major release

Use ES6/CommonJS/AMD modules instead. Capability sharing can be accomplished in vanilla JavaScript using prototypical inheritance or composition.


Original answer (Marionette pre 2.0)

You're right, you can't create modules like that; you have to use the App.module() pattern.

It's unusual that you're creating multiple application instances. Your typical setup has a single Application instance with Modules and subModules used to partition the site into logical areas, like so:

var MyApp = new Marionette.Application();

MyApp.module('forums', function(mod, app) {});
MyApp.module('gallery', function(mod, app) {});
MyApp.module('gallery.kitchen', function(mod, app) {});
MyApp.module('gallery.diningroom', function(mod, app) {});

MyApp.start();

If you want numerous modules to have similar capability (or to have the same initial definition), the module method can be called multiple times with the same module name to change the functionality. This can be used to create a base module of sorts that can be extended:

var MyApp = new Marionette.Application();

// Create your shared definition:
var ModuleDefaults = { definition: function(mod, app) {
  mod.type = 'gallery';
  mod.addInitializer(function() { /* do work */ });
}};
// create your modules (quickly!)
_.each(['forums', 'gallery', 'gallery.kitchen', 'gallery.master'],
  function(moduleName) {
    MyApp.module(moduleName, ModuleDefaults.definition);
});

// override whatever your want:
MyApp.module('forums', function(mod, app) {
  mod.type = 'forum';
  mod.addFinalizer(function() { /* take out the papers and the trash */ });
});

MyApp.start();

Upvotes: 2

Related Questions