Skip to content

Commit

Permalink
Add option to configure Application channels
Browse files Browse the repository at this point in the history
As discussed in #1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
  • Loading branch information
cmaher authored and samccone committed Jul 19, 2014
1 parent af376fe commit 5310b09
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 12 deletions.
21 changes: 14 additions & 7 deletions docs/marionette.application.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ var MyApp = new Backbone.Marionette.Application();
* [Adding Initializers](#adding-initializers)
* [Application Event](#application-event)
* [Starting An Application](#starting-an-application)
* [The Global Channel](#the-global-channel)
* [The Application Channel](#the-application-channel)
* [Event Aggregator](#event-aggregator)
* [Request Response](#request-response)
* [Commands](#commands)
* [Accessing the Global Channel](#accessing-the-global-channel)
* [Accessing the Application Channel](#accessing-the-application-channel)
* [Regions And The Application Object](#regions-and-the-application-object)
* [jQuery Selector](#jquery-selector)
* [Custom Region Class](#custom-region-class)
Expand Down Expand Up @@ -114,11 +114,17 @@ var options = {
MyApp.start(options);
```

## The Global Channel
## The Application Channel

Marionette Applications come with a [messaging system](http://en.wikipedia.org/wiki/Message_passing) to facilitate communications within your app.

The messaging system on the Application is the global channel from Backbone.Wreqr, which is actually comprised of three distinct systems.
The messaging system on the Application is the radio channel from Backbone.Wreqr, which is actually comprised of three distinct systems.

Marionette Applications default to the 'global' channel, but the channel can be configured.

```js
var MyApp = new Marionette.Application({ channelName: 'appChannel' });
```

This section will give a brief overview of the systems; for a more in-depth look you are encouraged to read
the [`Backbone.Wreqr` documentation](https://github.com/marionettejs/backbone.wreqr).
Expand Down Expand Up @@ -184,14 +190,15 @@ MyApp.commands.execute("fetchData", true);
MyApp.execute("fetchData", true);
```

### Accessing the Global Channel
### Accessing the Application Channel

To access this global channel from other objects within your app you are encouraged to get a handle of the systems
To access this application channel from other objects within your app you are encouraged to get a handle of the systems
through the Wreqr API instead of the Application instance itself.

```js
// Assuming that we're in some class within your app,
// it is preferable to access the global channel like this:
// and that we are using the default 'global' channel
// it is preferable to access the channel like this:
var globalCh = Backbone.Wreqr.radio.channel('global');
globalCh.vent;

Expand Down
51 changes: 51 additions & 0 deletions spec/javascripts/application.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,55 @@ describe('marionette application', function() {
expect(this.startStub).to.have.been.calledOnce.and.calledWith(this.fooOptions);
});
});

describe('radio channels', function() {
describe('when channelName is specified', function() {
beforeEach(function() {
this.channelName = 'foo';
this.App = Marionette.Application.extend({ channelName: 'foo' });
this.app = new this.App();
this.channel = Backbone.Wreqr.radio.channel(this.channelName);
});

it('should create a Wreqr channel on this.channel', function() {
expect(this.app.channel).to.deep.equal(this.channel);
});

it('should set the app EventAggregator to the channel vent', function() {
expect(this.app.vent).to.deep.equal(this.channel.vent);
});

it('should set the app Commands to the channel commands', function() {
expect(this.app.commands).to.deep.equal(this.channel.commands);
});

it('should set the app RequestResponse to the channel reqres', function() {
expect(this.app.reqres).to.deep.equal(this.channel.reqres);
});
});

describe('when channelName is set as function', function() {
beforeEach(function() {
this.channelName = 'foo';
this.channelNameStub = this.sinon.stub().returns(this.channelName);
this.App = Marionette.Application.extend({ channelName: this.channelNameStub });
this.app = new this.App();
});

it('should set the app channelName to the result of channelName', function() {
expect(this.app.channelName).to.equal(this.channelName);
});
});

describe('when no channelName is specified', function() {
beforeEach(function() {
this.channelName = 'global';
this.app = new Marionette.Application();
});

it('should set the app channelName to "global"', function() {
expect(this.app.channelName).to.equal(this.channelName);
});
});
});
});
15 changes: 10 additions & 5 deletions src/marionette.application.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
Marionette.Application = function(options) {
this._initializeRegions(options);
this._initCallbacks = new Marionette.Callbacks();
var globalCh = Backbone.Wreqr.radio.channel('global');
this.vent = globalCh.vent;
this.commands = globalCh.commands;
this.reqres = globalCh.reqres;
this.submodules = {};

_.extend(this, options);
this._initChannel();
};

_.extend(Marionette.Application.prototype, Backbone.Events, {
Expand Down Expand Up @@ -143,6 +139,15 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
});
},

// Internal method to setup the Wreqr.radio channel
_initChannel: function() {
this.channelName = _.result(this, 'channelName') || 'global';
this.channel = _.result(this, 'channel') || Backbone.Wreqr.radio.channel(this.channelName);
this.vent = _.result(this, 'vent') || this.channel.vent;
this.commands = _.result(this, 'commands') || this.channel.commands;
this.reqres = _.result(this, 'reqres') || this.channel.reqres;
},

// import the `triggerMethod` to trigger events with corresponding
// methods if the method exists
triggerMethod: Marionette.triggerMethod
Expand Down

0 comments on commit 5310b09

Please # to comment.