Been poking around the code base, but I don't see anything obvious that fills this need.
Does 4.x not have an anonymous pub/sub system in place?
Something akin to dojo's publish/subscribe functionality
http://davidwalsh.name/dojo-pub-sub
Been poking around the code base, but I don't see anything obvious that fills this need.
Does 4.x not have an anonymous pub/sub system in place?
Something akin to dojo's publish/subscribe functionality
http://davidwalsh.name/dojo-pub-sub
It doesn't, but I whipped up a simple mechanism you could extend to your liking:
Note - this is rudimentary - it doesn't have topic management (remove listeners and event declarations), but that could be added.Code:// Define Ext.define('PubSub', { extend: 'Ext.util.Observable', statics: { instance: null, subscribe: function (topic, listener, scope) { // Route messages through instance if (!PubSub.instance) { PubSub.instance = new this(); } var inst = PubSub.instance; // Ensure that event is declared if (!inst.events[topic]) { inst.addEvents(topic); } // Then listen on it, with declared scope inst.mon(inst, topic, listener, scope || inst); }, publish: function () { var inst = PubSub.instance; var args = Ext.Array.toArray(arguments); var topic = args[0]; // If the topic has been declared through subscribe if (inst && topic && inst.events[topic]) { // A quirk in Observable requires me to lowercase the topic name // I could have used inst.fireEvent(topic, args.slice(1)) // but the listener would get the args as a single array // parameter in arguments[0]. // This allows the published arguments to be passed properly. var evt = inst.events[topic.toLowerCase()]; evt.fire.apply(evt, args.slice(1)); } } } }); // Subscribe PubSub.subscribe('testTopic', function (a, b) { alert(a + ' = ' + b); }, this); PubSub.subscribe('testTopic', function (a, b) { alert(a + ' != ' + b); }, this); // Publish PubSub.publish('testTopic', 'x', 5);
hope this helps,
stevil
You should be able to port to Ext this jQuery pub/sub plugin based on Dojo:
https://github.com/phiggins42/bloody...ster/pubsub.js
Yeah, I'm actually doing that right now, hanging it off observable.
I was just surprised there was nothing baked in. There are 3 or 4 plugins and extensions that look great from 3 or 4 years ago, I just assumed one of those would have made it's way into the main codebase by now.
It doesn't, but I whipped up a simple mechanism you could extend to your liking:
Note - this is rudimentary - it doesn't have topic management (remove listeners and event declarations), but that could be added.Code:// Define Ext.define('PubSub', { extend: 'Ext.util.Observable', statics: { instance: null, subscribe: function (topic, listener, scope) { // Route messages through instance if (!PubSub.instance) { PubSub.instance = new this(); } var inst = PubSub.instance; // Ensure that event is declared if (!inst.events[topic]) { inst.addEvents(topic); } // Then listen on it, with declared scope inst.mon(inst, topic, listener, scope || inst); }, publish: function () { var inst = PubSub.instance; var args = Ext.Array.toArray(arguments); var topic = args[0]; // If the topic has been declared through subscribe if (inst && topic && inst.events[topic]) { // A quirk in Observable requires me to lowercase the topic name // I could have used inst.fireEvent(topic, args.slice(1)) // but the listener would get the args as a single array // parameter in arguments[0]. // This allows the published arguments to be passed properly. var evt = inst.events[topic.toLowerCase()]; evt.fire.apply(evt, args.slice(1)); } } } }); // Subscribe PubSub.subscribe('testTopic', function (a, b) { alert(a + ' = ' + b); }, this); PubSub.subscribe('testTopic', function (a, b) { alert(a + ' != ' + b); }, this); // Publish PubSub.publish('testTopic', 'x', 5);
hope this helps,
stevil
Last edited by stevil; 18 Aug 2011 at 11:51 AM. Reason: formatting
The Dojo code is self-contained, so you don't need to use the Ext's Observable.
Replace the jQuery plugin pattern by wrapping up the Dojo code in the Ext singleton.
Ext.define('Ext.PubSub', {
singleton: true,
// Copy the Dojo code here
});
I think that's all you need to do, but I didn't test it.
Just in case anyone is looking for copy paste example, this is what I am using, with some success.
Code:/* ExtJs pub/sub plugin by Jon Sykes (jon@sykes.me) Loosely based on Dojo's Pub/Sub Topic handlers Code lifted heavily from the jquery implementation by Peter Higgins https://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js Original Discussion: http://www.sencha.com/forum/showthread.php?144261 */ var cache= {}; Ext.define("Ext.topic", { singleton: true, // the topic/subscription hash cache: {}, publish: function(/* String */topic, /* Array? */args){ // summary: // Publish some data on a named topic. // topic: String // The channel to publish on // args: Array? // The data to publish. Each array item is converted into an ordered // arguments on the subscribed functions. // // example: // Add an event listener to a grid that publishes to the // something/happened topic on select // // | listeners: { // | 'select' : function(grid, rowIndex, e){ // | Ext.topic.publish("something/happened", [rowIndex]); // | } // | } // this.cache[topic] && Ext.each(this.cache[topic], function(){ this.apply(Ext.topic, args || []); }); }, subscribe: function(/* String */topic, /* Function */callback){ // summary: // Register a callback on a named topic. // topic: String // The channel to subscribe to // callback: Function // The handler event. Anytime something is $.publish'ed on a // subscribed channel, the callback will be called with the // published array as ordered arguments. // // example: // Add an event listener to a panel that subscribes to the // something/happened topic and triggers it's handler function // // example: // | listeners:{ // | render: function(){ // | Ext.topic.subscribe("something/happened", this.handleChangeWell); // | } // | } // if(!this.cache[topic]){ this.cache[topic] = []; } this.cache[topic].push(callback); return [topic, callback]; // Array }, unsubscribe: function(/* Array */handle){ // summary: // Disconnect a subscribed function for a topic. // handle: Array // The return value from a $.subscribe call. // example: // | var handle = Ext.topic.subscribe("something/happened", function(){}); // | Ext.topic.unsubscribe(handle); // | // best practice would be to put these in an array and on destroy of // | // the parent widget loop through and unsubsribe to all the topics. var t = handle[0]; this.cache[t] && Ext.each(this.cache[t], function(idx){ if(this == handle[1]){ this.cache[t].splice(idx, 1); } }); } });
We've all gotten our hands dirty with ExtJS4's "MVC" by now I presume. If so, we certainly understand why this sort of anonymous message pub/sub functionality is *not* baked in: it would not be in the spirit of the new "MVC" functionality. This is a shame because I got high praise for an ExtJS3 app I wrote using pubsub, but moving on to my next app using ExtJS4 I was required to use the MVC functionality and did not fare so well. Next time I'm thinking of using only the views, models, stores and application: no controllers. Views can easily get a handle on the app's viewport, and between the application, viewport, and anonymous message pub/sub style of development, I believe I will have everything necessary to succeed, *without* controllers: I'll let the application and/or viewport provide this sort of central control for the entire application.
Can I use pub/sub pattern in the situation decoupling controllers? @jonsykes @jemptymethod