Skip to content

Commit d1cba51

Browse files
committed
listenTo equivalents for Commands and Requests.
1 parent 1ceb392 commit d1cba51

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

src/backbone.radio.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,25 @@ Radio.Commands = {
233233
}
234234
};
235235

236+
// listenTo equivalent for Commands
237+
var listenMethods = {complyFor: 'comply', complyForOnce: 'complyOnce'};
238+
_.each(listenMethods, function(implementation, method) {
239+
Radio.Commands[method] = function(obj, name, callback) {
240+
var listeningTo = this._listeningTo || (this._listeningTo = {});
241+
var id = obj._commandId || (obj._commandId = _.uniqueId('c'));
242+
listeningTo[id] = obj;
243+
if (!callback && typeof name === 'object') { callback = this; }
244+
if (implementation === 'once') {
245+
callback = _.compose(function(result) {
246+
this.stopListening(_.rest(arguments));
247+
return result;
248+
}, callback);
249+
}
250+
obj[implementation](name, callback, this);
251+
return this;
252+
};
253+
});
254+
236255
//
237256
// Backbone.Radio.Requests
238257
// A messaging system for requesting data.
@@ -322,6 +341,25 @@ Radio.Requests = {
322341
}
323342
};
324343

344+
// listenTo equivalent for Requests
345+
var listenMethods = {replyFor: 'reply', replyForOnce: 'replyOnce'};
346+
_.each(listenMethods, function(implementation, method) {
347+
Radio.Requests[method] = function(obj, name, callback) {
348+
var listeningTo = this._listeningTo || (this._listeningTo = {});
349+
var id = obj._requestId || (obj._requestId = _.uniqueId('r'));
350+
listeningTo[id] = obj;
351+
if (!callback && typeof name === 'object') { callback = this; }
352+
if (implementation === 'once') {
353+
callback = _.compose(function(result) {
354+
this.stopListening(_.rest(arguments));
355+
return result;
356+
}, callback);
357+
}
358+
obj[implementation](name, callback, this);
359+
return this;
360+
};
361+
});
362+
325363
//
326364
// Backbone.Radio.channel
327365
// Get a reference to a channel by name.

test/spec/commands.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,4 +475,61 @@ describe('Commands:', function() {
475475
.and.calledWith('commandTwo');
476476
});
477477
});
478+
479+
describe('when registering a command with `complyFor`, then executing it', function() {
480+
beforeEach(function() {
481+
this.CommandsTwo = _.clone(Backbone.Radio.Commands);
482+
this.callback = stub();
483+
this.Commands.complyFor(this.CommandsTwo, 'myCommand', this.callback);
484+
this.CommandsTwo.command('myCommand');
485+
});
486+
487+
it('should execute the callback with the correct context', function() {
488+
expect(this.callback)
489+
.to.have.been.calledOnce
490+
.and.to.have.always.been.calledOn(this.Commands);
491+
});
492+
});
493+
494+
describe('when registering a command with `complyFor` and an event map, and then executing one of the commands', function() {
495+
beforeEach(function() {
496+
this.CommandsTwo = _.clone(Backbone.Radio.Commands);
497+
this.callbackOne = stub();
498+
this.callbackTwo = stub();
499+
this.Commands.complyFor(this.CommandsTwo, {
500+
commandOne: this.callbackOne,
501+
commandTwo: this.callbackTwo
502+
});
503+
this.CommandsTwo.command('commandOne');
504+
});
505+
506+
it('should execute the callback with the correct context', function() {
507+
expect(this.callbackOne)
508+
.to.have.been.calledOnce
509+
.and.to.have.always.been.calledOn(this.Commands);
510+
});
511+
512+
it('should not execute the callbacks not specified', function() {
513+
expect(this.callbackTwo).to.not.have.been.called;
514+
});
515+
});
516+
517+
describe('`complyForOnce` should clean up after itself', function() {
518+
beforeEach(function() {
519+
this.CommandsTwo = _.clone(Backbone.Radio.Commands);
520+
this.callback = stub();
521+
this.Commands.complyForOnce(this.CommandsTwo, 'myCommand', this.callback);
522+
this.CommandsTwo.command('myCommand');
523+
});
524+
525+
it('should execute the callback with the correct context', function() {
526+
expect(this.callback)
527+
.to.have.been.calledOnce
528+
.and.to.have.always.been.calledOn(this.Commands);
529+
});
530+
531+
it('should remove the reference from the original object', function() {
532+
expect(this.CommandsTwo._commands).to.deep.equal({});
533+
});
534+
});
478535
});

0 commit comments

Comments
 (0)