publisher-guide.js | |
---|---|
This is a guide to the | |
| |
Please use github issues to report any bugs. Pull requests welcome! | |
Installation - Universal JavaScript support
| |
AMD (RequireJS) installation | |
Place | require(['path/to/publisher'], function (publisher) {
/* Do stuff with publisher here */
}); |
Node.js InstallationInstall with npm | |
Include like everything else | var publisher = require('publisher'); |
Other browser usage | |
If neither AMD nor Node.js are detected, publisher is global with a
| publisher;
var myPublisher = publisher.noConflict(); |
All of the usage is identical among environments. | |
Basic Example | |
Subscribing to a topic | |
First you "subscribe" to a topic, and provide a handler to call when the topic is published. | publisher.subscribe('onAwesome', function () {
console.log('awesome');
}); |
Publishing a topic | |
When interesting things happen in your application, you publish the topic of interest. Any attached subscription handlers will be called. In this case, the console will log "awesome". | publisher.publish('onAwesome'); |
Publish with arguments | |
You can also send along some arguments that your subscriptions may be interested in when you publish. | publisher.subscribe('onAwesome', function (one, two, foo){
console.log(one, two, foo);
});
publisher.publish('onAwesome', 1, 2, 'foo'); |
Widget example | |
The topic name is simply a string, which is often namespaced to objects in the applicaton and then the method or action they are taking. | var datepicker = {
open: function (){
/* some real code */
publisher.publish('datepicker/open');
},
select: function (){
var oldValue = this.input.value,
newValue = this.getSelected();
/* some real code */
publisher.publish('datepicker/select', newValue, oldValue);
},
close: function (){
/* some real code */
publisher.publish('datepicker/close');
}
}; |
Subscribe to all the topics | publisher.subscribe('datepicker/open', function () {
blurOtherStuff();
});
publisher.subscribe('datepicker/select', doSomeThingOnDateSelect);
publisher.subscribe('datepicker/close', theForm.submit.bind(theForm)); |
Creating Individual Publishers | |
While | var datepicker = publisher({
open: function (){ |
| this.publish('open');
},
select: function (){
this.publish('select', newValue, oldValue);
},
close: function (){
this.publish('close');
}
}); |
| datepicker.subscribe('open', doSomethingOnOpen); |
This pattern makes extending the behavior of an object trivial. | |
You can also create a generic publisher by calling publisher with no arguments at all. | var localPub = publisher();
localPub.subscribe('topic', function() {});
localPub.publish('topic'); |
Binding the context of handlers to other objects | |
Subscription handlers are naturally bound to the publisher. We can verify this behavior in our previous examples. | publisher.subscribe('onAwesome', function () {
console.log(this === publisher); //> true
});
datepicker.subscribe('open', function () {
console.log(this === datepicker); //> true
}); |
Sometimes you may want to change the context of the method, | var context = {};
publisher.subscribe('onAwesome', function () {
console.log(this === context); //> true
}, context); |
It's useful when calling the method of another object | publisher.subscribe('onAwesome', datepicker.open, datepicker); |
But that's ugly, so publisher has some alternate signatures. | |
Alternate subscription signatures | |
The "hitch" subscription signature | |
If you name object methods after a topic, you can simply "hitch" the object. Publisher will create a subscription on the topic matching the object's method name, and sets the object as the context of the handler. | datepicker.onAwesome = function(){
this.open(); // this is datepicker
};
publisher.subscribe(datepicker, 'onAwesome'); |
which is functionally equivalent to, but much better looking than: | publisher.subscribe('onAwesome', datepicker.onAwesome, datepicker); |
This is really useful for publishing application events like domready:
All objects that care about the event can have a method named
| |
Assuming we're using jQuery... | datepicker.domready = function () {
this.element = $('#some_element');
}
publisher.subscribe(datepicker, 'domready'); |
elsewhere in the app | $(function () {
publisher.publish('domready');
}); |
The "hitch multiple" subscribe signature | |
Often your subscriber will be interested in multiple topics, doing this gets annoying: | publisher.subscribe(datepicker, 'domready');
publisher.subscribe(datepicker, 'calendar:on');
publisher.subscribe(datepicker, 'calendar:off'); |
Instead, publisher supports an array for the second argument, so when your object has multiple methods with names matching topics you want to subscribe to, you can do it in one statement. | publisher.subscribe(datepicker, [
'domready',
'calendar:on',
'calendar:off'
]); |
subscribing multiple handlers | |
You can also subscribe to multiple topics at once, so instead of doing them all individually: | publisher.subscribe('foo', function(){});
publisher.subscribe('bar', function(){}); |
You can do them all at once | publisher.subscribe({
'foo': function(){},
'bar': function(){}
}); |
Subscription ObjectsThe
| |
Store the subscription in a variable | var subscription = publisher.subscribe('foo', function () {
console.log('hello');
}); |
console logs 'foo' | publisher.publish('foo'); |
Detach the subscription and console logs nothing | subscription.detach();
publisher.publish('foo'); |
Attach the subscription and things are back to normal | subscription.attach();
publisher.publish('foo'); |
The methods return the subscription object so you can detach upon creation | var subscription2 = publisher.subscribe('foo', function () {
console.log('foo 2');
}).detach(); |
Signatures that create several subscriptions at once return a collection of handlers of the same type. | var subscriptions = publisher.subscribe({
foo: function() {},
bar: function() {}
});
subscriptions.foo.detach();
subscriptions.bar.attach();
var hitchSubscriptions = publisher.subscribe(datepicker, [
'domready',
'calendar:on',
'calendar:off'
]);
hitchSubscriptions[0].detach();
hitchSubscriptions[1].detach(); // etc. |
Advising ObjectsDeprecated. If you are one of the few crazy folks who used this (like me), please use advise.js to get this back. I'll be writing a shim soon to show here. | |