Ext.ux.MsgBus Plugin

This is an archived post from the ExtJS era — the code may be obsolete, but the principles often still apply.

Code in this post can be obsolete, however, principles and theory may still apply.

Recently I've been looking for a better way of inter-component communication in Ext so I've read a couple of posts with Message Bus implementations, I've skimmed over OpenAjax Hub page but I haven't found anything suitable for my needs. The first approach was the Simple Message Bus example but that is more concept proof than a really usable way in production environment. I like the concept of message subjects (topics) as dot separated sequence of tokens with the ability to subscribe to messages with specific subjects and with wildcard support. For example, if a component would subscribe to the subject eu.extjs.desktop.** it would receive message with subject eu.extjs.desktop.wallpaper.set but it wouldn't receive message eu.extjs.taskbar.hide. So this plugin was born. Ext.ux.MsgBus fits in any component that is descendant of Ext.util.Observable and it does not need any other changes/overrides. You would stick it only into the components that must participate in bus messaging. It adds subscribe and publish methods to the component. Usage example:

The above would call p.onWallpaper callback once upon the receipt of a "wallpaper" message. Other example:

I haven't tested it fully yet so take it more as an initial idea than as a bullet-proof, worldwide-tested code. Also, I didn't try in any means to implement OpenAjax standards and use this plugin for an inter library communication. Consider it as a one possibility of intra-Ext, inter-component communication. Any comments and/or bug reports are welcome.

Enjoy! The accompanying example is no longer online.

28 comments

  1. Charles HimmerSeptember 21, 2009archive
    Great idea Saki. I love your blog and examples. I had a question though. What advantages does this give you over using Ext's built in custom event functions?
  2. SakiSeptember 21, 2009archive
    <b>Selective</b> event listening. If you listen to global events (bus events) you can ignore maybe 90% of them. With MsgBus you can say which "category" you process.
  3. Jorge MarianiSeptember 22, 2009archive
    Saki, this plugin rules. Question: How do I set the subscription during the initComponent function? ie: ,initComponent:function() { var config = { bla bla bla Ext.apply(this, Ext.apply(this.initialConfig, config)); bdApp.appVW.superclass.initComponent.apply(this, arguments); this.subscribe('bdApp.mainMenu.nodeClick'); } // eo function initComponent The subscription fails (this.subscribe is not a function [Break on this error] this.subscribe('bdApp.mainMenu.nodeClick');\n) TIA!
  4. SakiSeptember 22, 2009archive
    Plugins are initialize after the initComponent runs. You can subscribe at the end of constructor override. If you want to know more details post please a forum query and send me the link to the post.
  5. Mike RobinsonSeptember 22, 2009archive
    Love the plugin. I want to attach it to a Ext.data.Store, which (not being a component) does not have a "plugins" list. It seemed to work when I did this: var q = new Ext.ux.MsgBus; q.init(ds_batches); ds_batches.subscribe('foobar', {fn: ds_batches.onFoobar}); I want to use messages to let a form tell a data-store that a new record needs to be posted and maybe many other things. schweet!
  6. Mike RobinsonSeptember 22, 2009archive
    P.S. I faithfully copied the "single: true" from your example but it seemed to have no particular effect. I therefore not quite sure why you had it in your example. If there WAS a particular reason for it, please advise.
    1. SakiSeptember 22, 2009archive
      To tell truth, I haven't tested it thoroughly, but the listener should be installed with options from config. I need to debug if not... :(
  7. SakiSeptember 23, 2009archive
    @Mike, it was a bug in fact; I've already fixed it in the above code. Can you re-test please?
  8. jeu simulationSeptember 25, 2009archive
    great job saki! really! But I have got a little problem. I would like to use msgTarget = "side" to notify validation error to the user. How can I fix it? Thank you in advance for posting answer.
  9. SumitSeptember 26, 2009archive
    @Jorge Mariani You can also put subscription code in onRender part of your extension: Eg: onRender: function(){ MyComponent.ContentPane.superclass.onRender.apply(this, arguments); this.subscribe(\'App.MainMenu.nodeClick\', {fn:this.nodeClick}); }
  10. SakiSeptember 28, 2009archive
    Yes, placing subscriptions in onRender shall work.
  11. Jorge MarianiOctober 16, 2009archive
    Using onRender worked like a charm. Thank you!
  12. dixonApril 7, 2010archive
    Nice plug-in! I will probably use it in one of my projects. Therefore I would need some information: is it possible to add the publish and un-/subscribe methods to the prototype instead to each object instance? Or do you think that\'s not a good idea ...
  13. PlantApril 19, 2010archive
    Great plugin, it matched my needs exactly. I just had one question: before a subscriber component is destroyed, should it unsubscribe from all messages? It seems to me as if this is necessary to avoid orphaned subscriptions being left in the bus. If it is neccessary, this seems to do the trick : for (subject in this.subs) { result = this.unsubscribe(subject); } Maybe it could be added to a function called on the beforedestroy event, as part of the plug in?
  14. MichaelMay 8, 2010archive
    Saki, is there a way to use this to build a chat? So two people on two different computers could chat?
  15. KonstantinJune 18, 2010archive
    If you attach plugin to Ext.util.Observable or to your class, that extends Observable, it does not work. I wanted it for my core classes which just do some work, they do not appear visually. But ended up with changing parent for these classes to Ext.Component in order to get it working OK.
  16. joeAugust 13, 2010archive
    re: Konstantin I think that is a limitation of Ext, since direct Observable descendents to not take the "plugin" property. tried it on a RowSelectionModel instance and it failed as well.
  17. joeAugust 13, 2010archive
    Very useful stuff indeed. My approach of what I started today before i found your blog post was an event broker component that would pool all events that are relayed to it. Although I do prefer your solution of a message bus. However, my approach was hooking the necessary code right into Ext.util.Observable, so that all objects that are descendants of Observable could communicate (right now anything thats not of the Component class won't accept plugins). However, I failed to override Ext.util.Observable properly, my skillz are not at leet ;) I'd love to any pointers by anyone on how to override Ext.util.Observable properly, since it seems to be quite different to overriding Component, to fit the code into the override and have the messagebus be accessible by any descendant of Observable.
  18. SakiAugust 16, 2010archive
    Take a look at forum and/or learn section of http://sencha.com/learn Hint: override constructor.
  19. TottiSeptember 9, 2010archive
    Very nice idea. I'm gonna use this for my current project as to reduce the coupling.
  20. RedJanuary 18, 2012archive
    I am little confused about how the actual filtering is performed. Because the subscription is always done for 'message' and the publish always fires the 'message' event. Is the filtering used in the publish method? I am trying to get this to work on ExtJs4..it works allright..but Its basically working by creating a listener for message and firing an event on it. No subject filtering as expected. What am I doing wrong?
  21. VijayJuly 9, 2012archive
    Can you write the example by using msgbus plugin in Object Oriented manner ? Why because if components are there in a single page it is nicely working.. But i want in object oriented manner i dont't know how to do it in OOP style ?
  22. Rahul UmraoJuly 19, 2012archive
    If multiple component are in the same page then it is working fine ..but if in the object oriented manner how can i use publish/subscribe methods and most importantly where i use these methods in the component - for Ex- component 1(Ext.panel) having button and on button click i want to open a component 2 (Ext.panel) then how &amp; where i need to put publish and subscribe by using message bus plugins ...... please give me suggestion because of this i am not able to use correctly the message bus functionality .
  23. Lev DashevskiyApril 22, 2013archive
    Hello, Saki! First of all, thanks so much for all of your superb work - you seem to be everywhere (ExtJs is) ! :) Secondly, I wanted to ask you a question about the MsgBus. It probably is a broader question about the JavaScript scope and area of visibility. If I have 2 segments of JavaScript code within my HTML page code (that is 2 ... chunks, separated by other HTML), each of the chunks rendering some UI, is it possible to use a MsgBus instance to communicate between the 2 interfaces? Thanks.
  24. Oğuz ÇelikdemirApril 22, 2014archive
    Saki, it would be nice to see a syntax highlighter in your blog to be able to read easily code!
    1. SakiApril 22, 2014archive
      It shortly stopped to work after port. Syntax highlighter should be now up and running.
  25. jmchouletOctober 15, 2019archive
    Hello, I cannot get http://examples.learnfromsaki.com/?ex=msgbus example. Is it available yet? Jean-Marc
    1. sakiNovember 10, 2019archive
      Yeah it doesn’t work for some reason. I’m now away but I’ll take a look in a week or so.

Comments are closed on archived posts.