My colleague and buddy Eric Burley @eburley took the time to write down some excellent points around $watch vs PubSub that we have learned over the last year working with AngularJS on a large, non-trivial application. These golden nuggets were on an internal wiki that after a bit of prodding and pleading he was kind enough to post to a public place for everyone to see.
These are conclusions that we have arrived at over the course of a year after writing a LOT of AngularJS code. I highly respect Eric as an engineer and appreciate him taking the time to to articulate these thoughts in such a digestible manner.
So! Without further ado, check out the link below.
http://eburley.github.com/2013/01/31/angularjs-watch-pub-sub-best-practices.html
Cheers!
Great work guys.
much appreciated!
Looking at the pub sub example, I wonder what’s the benefit in going the long way in the controller. Why not directly attach the $scope.$on in the controller instead of having the service doing that for you.
I illustrate the change here:
http://jsfiddle.net/cburgdorf/pZ3cJ/
The only reason I could think of is that he thinks binding to the $scope in the controller is an implementation detail about how pub/sub works in AngularJS and he want’s to hide that from the controller so that the controller only uses the services for the pub/sub mechanism. But seems a bit like overengineering to me, since that’s just how broadcasting works in AngularJS. Or is there any other reason why he does it that way?
The example is a bit simplified, but I think there are a couple of benefits in keeping the message identifier and message parsing mechanisms in the channel:
For one, if you route everything through the channel you can do interesting things, like debounce spammy events, set breakpoints, log in one place, etc. I also like the ability to pack and unpack message parameters to call back in the style of your choosing (message publication and message subscription don’t have to have the same signatures), and add channel information to the message ( channel or service state, for example) unknown to the message publisher. You also get function calls that are usually more refactor friendly than hard coded strings.
my 2 cents obviously, and for a simple example possibly overkill.
Thanks Eric (and simpulton) for posting this. I used the PubSub approach presented to update “time ago” strings (i.e., using moment.js to display “a few seconds ago” or “2 hours ago”) in a project I’m working on. I also crated a “time-ago” directive to automatically handle subscribing to a “time-ago-tick” event. More details at http://stackoverflow.com/a/18115976/215945 if interested.
Hello!
Why didn’t you use a common and generic subscribe’s function that accepts the topic as parameter, instead of
writing manually all the subscribing function?
For example, with your implementation, in a specific channel, if i have four message to publish and subscribe I must write four
onMessage function and so on.
Or not?
Greetings from Italy dude, and really nice nice job!
Gabriele
Hi This was a very interesting article for me when looking for ways to comunication between components in Angular.
I wrote a Message Service based on Publish Subscribe design pattern.
https://github.com/ejmarino/angular-ms
I hope you can take a look. Any suggestions will be welcomed. 😀