Skip to content

listenTo equivalents for Commands and Requests. #157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: minor
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,20 @@ for an example.

Returns the instance of Commands.

#### `complyFor( other, commandName, callback )`

An analogous method to `Events.listenTo`. Registers a callback on `other`. The advantage to using this form is that it allows the object
to remove its own handlers at a later date. This is particularly useful for registering events on a channel.

#### `complyForOnce( other, commandName, callback )`

An analogous method to `Events.listenToOnce`. Just like `complyFor`, but the callback will only be executed once before being removed.

#### `stopComplyingFor( [other] [, commandName] [, callback] )

An analogous method to `Events.stopListening`. Removes callbacks registered on `other`. Pass no arguments to remove all callbacks,
or pass any combination of the arguments for fine-grained control over what is removed.

### Requests

#### `request( requestName [, args...] )`
Expand Down Expand Up @@ -333,6 +347,20 @@ You may also pass a hash of replies or space-separated replies to remove many at

Returns the instance of Requests.

#### `replyFor( other, requestName, callback )`

An analogous method to `Events.listenTo`. Registers a callback on `other`. The advantage to using this form is that it allows the object
to remove its own handlers at a later date. This is particularly useful for registering requests on a channel.

#### `replyForOnce( other, requestName, callback )`

An analogous method to `Events.listenToOnce`. Just like `replyFor`, but the callback will only be executed once before being removed.

#### `stopReplyingFor( [other] [, requestName] [, callback] )

An analogous method to `Events.stopListening`. Removes replies registered on `other`. Pass no arguments to remove all callbacks,
or pass any combination of the arguments for fine-grained control over what is removed.

### Channel

#### `channelName`
Expand Down
130 changes: 92 additions & 38 deletions src/backbone.radio.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,10 @@ function removeHandlers(store, name, callback, context) {
return matched;
}

/*
* tune-in
* -------
* Get console logs of a channel's activity
*
*/
//
// tune-in
// Get console logs of a channel's activity
//

var _logs = {};

Expand Down Expand Up @@ -150,12 +148,10 @@ _.extend(Radio, {
}
});

/*
* Backbone.Radio.Commands
* -----------------------
* A messaging system for sending orders.
*
*/
//
// Backbone.Radio.Commands
// A messaging system for sending orders.
//

Radio.Commands = {

Expand Down Expand Up @@ -232,16 +228,47 @@ Radio.Commands = {
debugLog('Attempted to remove the unregistered command', name, this.channelName);
}

return this;
},

stopComplyingFor: function(obj, name, callback) {
var complyingFor = this._complyingFor;
if (!complyingFor) { return this; }
var remove = !name && !callback;
if (!callback && typeof name === 'object') { callback = this; }
if (obj) { (complyingFor = {})[obj._commandId] = obj; }
for (var id in complyingFor) {
obj = complyingFor[id];
obj.stopComplying(name, callback, this);
if (remove || _.isEmpty(obj._commands)) { delete this._complyingFor[id]; }
}
return this;
}
};

/*
* Backbone.Radio.Requests
* -----------------------
* A messaging system for requesting data.
*
*/
// listenTo equivalent for Commands
var listenMethods = {complyFor: 'comply', complyForOnce: 'complyOnce'};
_.each(listenMethods, function(implementation, method) {
Radio.Commands[method] = function(obj, name, callback) {
var complyingFor = this._complyingFor || (this._complyingFor = {});
var id = obj._commandId || (obj._commandId = _.uniqueId('c'));
complyingFor[id] = obj;
if (!callback && typeof name === 'object') { callback = this; }
if (implementation === 'once') {
callback = _.compose(function(result) {
this.stopListening(_.rest(arguments));
return result;
}, callback);
}
obj[implementation](name, callback, this);
return this;
};
});

//
// Backbone.Radio.Requests
// A messaging system for requesting data.
//

function makeCallback(callback) {
return _.isFunction(callback) ? callback : _.constant(callback);
Expand Down Expand Up @@ -323,16 +350,47 @@ Radio.Requests = {
debugLog('Attempted to remove the unregistered request', name, this.channelName);
}

return this;
},

stopReplyingFor: function(obj, name, callback) {
var replyingFor = this._replyingFor;
if (!replyingFor) { return this; }
var remove = !name && !callback;
if (!callback && typeof name === 'object') { callback = this; }
if (obj) { (replyingFor = {})[obj._requestId] = obj; }
for (var id in replyingFor) {
obj = replyingFor[id];
obj.stopReplying(name, callback, this);
if (remove || _.isEmpty(obj._requests)) { delete this._replyingFor[id]; }
}
return this;
}
};

/*
* Backbone.Radio.channel
* ----------------------
* Get a reference to a channel by name.
*
*/
// listenTo equivalent for Requests
var listenMethods = {replyFor: 'reply', replyForOnce: 'replyOnce'};
_.each(listenMethods, function(implementation, method) {
Radio.Requests[method] = function(obj, name, callback) {
var replyingFor = this._replyingFor || (this._replyingFor = {});
var id = obj._requestId || (obj._requestId = _.uniqueId('r'));
replyingFor[id] = obj;
if (!callback && typeof name === 'object') { callback = this; }
if (implementation === 'once') {
callback = _.compose(function(result) {
this.stopListening(_.rest(arguments));
return result;
}, callback);
}
obj[implementation](name, callback, this);
return this;
};
});

//
// Backbone.Radio.channel
// Get a reference to a channel by name.
//

Radio._channels = {};

Expand All @@ -348,13 +406,11 @@ Radio.channel = function(channelName) {
}
};

/*
* Backbone.Radio.Channel
* ----------------------
* A Channel is an object that extends from Backbone.Events,
* Radio.Commands, and Radio.Requests.
*
*/
//
// Backbone.Radio.Channel
// A Channel is an object that extends from Backbone.Events,
// Radio.Commands, and Radio.Requests.
//

Radio.Channel = function(channelName) {
this.channelName = channelName;
Expand All @@ -372,13 +428,11 @@ _.extend(Radio.Channel.prototype, Backbone.Events, Radio.Commands, Radio.Request
}
});

/*
* Top-level API
* -------------
* Supplies the 'top-level API' for working with Channels directly
* from Backbone.Radio.
*
*/
//
// Top-level API
// Supplies the 'top-level API' for working with Channels directly
// from Backbone.Radio.
//

var channel, args, systems = [Backbone.Events, Radio.Commands, Radio.Requests];

Expand Down
Loading