PDA

View Full Version : Ext.ux.BroadcastEvents -application level events (aka broadcasting) v0.5



SamuraiJack1
3 Jun 2008, 8:47 AM
Documentation and download links are available here:
http://extjs-ux.org/docs/?class=Ext.ux.event.Broadcast

Note, that internally all events are defined on singleton

Ext.ux.BroadcastEvents = new Ext.util.Observable;So you can manage your events also directly through its methods.

nassaja-rus
4 Jun 2008, 4:38 AM
Ext.ux.BroadcastEvents.events is undefined
[Break on this error] var ce = Ext.ux.BroadcastEvents.events[arguments[0].toLowerCase()];

nassaja-rus
4 Jun 2008, 4:50 AM
myClass = function ()
{
this.addEvents({
"fired": true
});
}

Ext.extend(
myClass,
Ext.util.Observable,
{

init: function()
{

this.publish('fired');

}
}
);

nassaja-rus
4 Jun 2008, 5:33 AM
Great plugin, thank's!

fangzhouxing
4 Jun 2008, 7:57 AM
How about Tibco PageBus? Any different?

SamuraiJack1
4 Jun 2008, 11:07 AM
"Ext.ux.BroadcastEvents.events is undefined" - that mean that file with plugin didn't loaded properly and singleton Ext.ux.BroadcastEvents is not created yet.

That error message appears for that code? Please publish ), a mean post whole file.

SamuraiJack1
4 Jun 2008, 11:34 AM
How about Tibco PageBus? Any different?

Dont know much about Tibco PageBus. This plugin provides Observable features ( addListener and fireEvent defined as subscribe and publish) for broadcasting events. Any Observable (or its subclass) can "publish" event and any Observable (or its subclass) can "subscribe" for it.
So you can use it with almost any object in your app. Subscribing and publishing is performing exactly the same as with ordinary Ext events, so timing, scoping, one-time handlers also provided.

Any suggestion about missing functionality (comparing with Tibco for example) are welcome.

nassaja-rus
4 Jun 2008, 11:59 PM
It is necessary to add a inherited method for events addition from my object in a plug-in Ext.ux.BroadcastEvents object.

Because this.addEvents adds events in itself(myClass), but not in Ext.ux.BroadcastEvents. And when I try this.publish, it addresses directly to object Ext.ux.BroadcastEvents. But in it there are no events.

Or to make so, that the Ext.ux.BroadcastEvents object would understand events from my myClass object, which added with this.addEvents();

What you think?



//this will work, because I add event directly in Ext.ux.BroadcastEvents
myClass = function ()
{
//this.addEvents({
// "fired": true
//});
Ext.ux.BroadcastEvents.addEvents({
"fired": true
});
}

Ext.extend(
myClass,
Ext.util.Observable,
{
init: function()
{
this.publish('fired');
}
}
);

SamuraiJack1
5 Jun 2008, 8:50 AM
Actually event is adding during "subscribe". So you can freely "publish" it, without adding - if any of your objects have already "subscribed" for this event - it will be already added.
If none of your objects have subscribed - nothing will happened as expected.
So that code in myClass constructor can be removed.

rainydays
30 Jun 2008, 8:58 AM
Actually event is adding during "subscribe". So you can freely "publish" it, without adding - if any of your objects have already "subscribed" for this event - it will be already added.

That's true. However, if no-one has subscribed to anything then Ext.ux.BroadcastEvents.events will be undefined.

Thanks for a great plugin anyhow!

SamuraiJack1
30 Jun 2008, 9:49 AM
That's true. However, if no-one has subscribed to anything then Ext.ux.BroadcastEvents.events will be undefined.

yes:


If none of your objects have subscribed - nothing will happened as expected.

rainydays
30 Jun 2008, 12:19 PM
Well my point was that something does happen. It throws an error saying that events is undefined. I would say it's a bug in Observable.js right?

SamuraiJack1
30 Jun 2008, 2:33 PM
Its not a bug in Observable, its just a Do What I Mean principle - if i'm firing not defined event - then do nothing.

rainydays
30 Jun 2008, 4:00 PM
If no subscriptions has been made then the events variable isn't defined.


var ce = Ext.ux.BroadcastEvents.events[arguments[0].toLowerCase()];

will then try to access a variable that isn't defined and will result in an error. which can possibly happen if the subscribing components hasn't been instantiated but the publishing components has.

No biggie, but still a bug in my book. defining the events variable solves it.

SamuraiJack1
1 Jul 2008, 3:05 AM
Seems you are right, publishing event before any subscriptions will throw exception.
I've fixed it in the 1st post.

architect
8 Jul 2008, 11:37 PM
Great work. That's exactly what I need.

jack.slocum
18 Oct 2008, 1:57 PM
I have used something similar in my application development as the primary namespace. e.g.


xds = new Ext.util.Observable();
xds.addEvents('login', 'sessiontimeout');

then I can publish and subscribe using the standard Ext observable functionality:


xds.on('login', this.doSomething, this);

What does the plugin provide that this is missing?

Thanks.

hendricd
18 Oct 2008, 2:00 PM
Afraid I jumped (https://extjs.com/forum/showthread.php?t=42942)on that concept, too. ;) Just wrapped it a bit differently.

SamuraiJack1
19 Oct 2008, 1:04 AM
This plugin provides the unified way for broadcasting - which allows the broadcasting to be used in another plugins and extensions (which are not aware about the xds variable in your example).

In other aspects the approaches are equal.

ThorstenSuckow
19 Oct 2008, 5:14 AM
This plugin provides the unified way for broadcasting - which allows the broadcasting to be used in another plugins and extensions (which are not aware about the xds variable in your example).

In other aspects the approaches are equal.

Although I worked on a similiar implementation like you, I think Jack's approach is pretty neat - simply wrap xsd in a singleton and there you go.

SamuraiJack1
19 Oct 2008, 11:13 AM
Although I worked on a similiar implementation like you, I think Jack's approach is pretty neat - simply wrap xsd in a singleton and there you go.

Yeah, its exactly how Ext.ux.BroadcastEvents is working.

fxmisticat
28 Oct 2008, 3:43 AM
how do I use Broadcast.js? it has declare(' at the top of the js file?

SamuraiJack1
28 Oct 2008, 5:08 AM
how do I use Broadcast.js? it has declare(' at the top of the js file?

Yes, its a package declaration for jScout (http://extjs.com/learn/JScout). With it you can dynamically load Ext.ux.event.Broadcast with the call like:

use('Ext::ux::event::Broadcast', function () {
....
your code, depended on broadcasting

});You can also simply remove the "declare(" statement and matching brackets at the end.

fxmisticat
28 Oct 2008, 5:38 AM
thanks SamuraiJack.. jScout looks very interesting..

SamuraiJack1
28 Oct 2008, 5:49 AM
Here are some more examples:

basic:
http://extjs-ux.org/docs/?class=Ext.ux.panel.MenuPanel
http://extjs-ux.org/repo/authors/SamuraiJack/trunk/Ext/ux/panel/MenuPanel/menus.html

advanced:
http://extjs-ux.org/docs/?class=Ext.ux.api.gMap
http://extjs-ux.org/repo/authors/SamuraiJack/trunk/Ext/ux/api/gMap/demo.html

rvwong
30 Nov 2008, 3:29 PM
Here are some more examples:

basic:
http://extjs-ux.org/docs/?class=Ext.ux.panel.MenuPanel
http://extjs-ux.org/repo/authors/SamuraiJack/trunk/Ext/ux/panel/MenuPanel/menus.html

advanced:
http://extjs-ux.org/docs/?class=Ext.ux.api.gMap
http://extjs-ux.org/repo/authors/SamuraiJack/trunk/Ext/ux/api/gMap/demo.html

Great plugin SamuraiJack! But I'm a little unclear as to how the following examples you linked in provide good examples at to its use...

SamuraiJack1
1 Dec 2008, 2:30 AM
Ah, forget to mentioned - click on "Defined In" link on each page (or look on sources of .html file)

rvwong
1 Dec 2008, 9:07 AM
Ah, forget to mentioned - click on "Defined In" link on each page (or look on sources of .html file)

Sorry SamuraiJack, are we talking about examples for the Broadcast plugin? or JScout??
for example two of your links ( the basic example ones ) both link to the MenuPanel extension panel example. For the life of me I can't see any references to the use of the Ext.ux.Broadcast plugin. Am I missing something??

I also noticed that with the source given with the example, if you just remove the declare( 'Ext::ux::... line along with the corresponding excompassing braces, it will not work. The line at the bottom,
Ext.ux.event.Broadcast = new Ext.util.Observable; needs to be preceded by a line like:

Ext.namespace('Ext.ux.event');

I'm not sure if its just me, ( a newbie to all this ), but I don't have that namespace defined in my project.

Thanks...

SamuraiJack1
1 Dec 2008, 9:17 AM
I was talking (in the thread context) about jScout examples.

As about BroadCast, may be this link will help : http://extjs-ux.org/docs/?class=Ext.ux.event.Broadcast

jmariani
1 Dec 2008, 2:42 PM
I'm getting this error during a:


this.subscribe('currencyAdded', function(){this.store.reload();},this);

Looks like I wasn't capable of creating a Broadcast.js without the JScout stuff.

Would you publish a JS without that, please?

Thank you in advance.

SamuraiJack1
1 Dec 2008, 2:45 PM
just remove wrapping declare() call

jmariani
1 Dec 2008, 2:49 PM
I did, but I get that error.

Here's the code:

Ext.namespace('Ext.ux.event');
//declare( 'Ext::ux::event::Broadcast', function (use,checkState,__PACKAGE__) {
//function Ext.ux.event.Broadcast(){
Ext.override(Ext.util.Observable, {

/**
* This function is <b>addListener</b> analog for broadcasted messages. It accept the same parameters and have the same functionality. For further details please refer to <b>Ext.util.Observable</b> documentation
* @name subscribe
* @methodOf Ext.ux.event.Broadcast
* @param {String} eventName
* @param {Function} fn
* @param {Object} scope
* @param {Object} o
*/
subscribe: function(eventName, fn, scope, o) {
Ext.ux.event.Broadcast.addEvents(eventName);
Ext.ux.event.Broadcast.on(eventName, fn, scope, o);
},


/**
* This function is <b>fireEvent</b> analog for broadcasted messages. It accept the same parameters and have the same functionality. For further details please refer to <b>Ext.util.Observable</b> documentation
* @name publish
* @methodOf Ext.ux.event.Broadcast
* @param {String} eventName
* @param {Object} args Variable number of parameters are passed to handlers
* @return {Boolean} returns false if any of the handlers return false otherwise it returns true
*/
publish : function() {
if(Ext.ux.event.Broadcast.eventsSuspended !== true){
var ce = Ext.ux.event.Broadcast.events ? Ext.ux.event.Broadcast.events[arguments[0].toLowerCase()] : false;
if(typeof ce == "object"){
return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
}
}
return true;
},

/**
* This function is <b>removeListener</b> analog for broadcasted messages.
* @name removeSubscriptionsFor
* @methodOf Ext.ux.event.Broadcast
* @param {String} eventName The type of event which subscriptions will be removed. If this parameter is evaluted to false, then ALL subscriptions for ALL events will be removed.
*/
removeSubscriptionsFor : function(eventName) {
for(var evt in Ext.ux.event.Broadcast.events) {
if ( (evt == eventName) || (!eventName) ) {
if(typeof Ext.ux.event.Broadcast.events[evt] == "object"){
Ext.ux.event.Broadcast.events[evt].clearListeners();
}
}
}
}

});
//});

SamuraiJack1
1 Dec 2008, 2:54 PM
Seems you've accidentally cut this line also:


Ext.ux.event.Broadcast = new Ext.util.Observable;here's the link to full sources:
http://extjs-ux.org/repo/trunk/Ext/ux/event/Broadcast.js

jmariani
1 Dec 2008, 2:57 PM
This is what I'm doing:

Somewhere in the code, I'm creating a grid and I'm trying to subscribe the grid to a message.
Later, within an edit window, after successfully saving a record to a database, I want to fire the event.

In the grid code, I'm doing this:
This code is executed first, because the window code didn't exist yet (it's loaded on demand from a remote store).

this.subscribe('currencyAdded', function(){this.store.reload();},this);

In the window save button, I'm doing this:


this.publish('currencyAdded');

When I try to use the grid, I'm getting:

Ext.ux.event.Broadcast is undefined

Do I need to set the event in an initialization code first? How?

jmariani
1 Dec 2008, 3:03 PM
Seems you've accidentally cut this line also:


Ext.ux.event.Broadcast = new Ext.util.Observable;here's the link to full sources:
http://extjs-ux.org/repo/trunk/Ext/ux/event/Broadcast.js

Yes, you're right. I removed it because I thought it was within the comments.

Thank you very much Your code is very good!

SamuraiJack1
1 Dec 2008, 3:41 PM
Yes, you're right. I removed it because I thought it was within the comments.

Thank you very much Your code is very good!

thanks ) try also jScout )

jmariani
1 Dec 2008, 4:36 PM
thanks ) try also jScout )

I will, looks very interesting since I'm developing a large application framework (the base idea comes from PeopleSoft) and probably I will produce a lot of js code.
As I understand, the main goal is to download the js's from the server on demand, instead of downloading the whole enchilada at the <HEAD/> of the page, right?

SamuraiJack1
2 Dec 2008, 1:34 AM
I will, looks very interesting since I'm developing a large application framework (the base idea comes from PeopleSoft) and probably I will produce a lot of js code.
As I understand, the main goal is to download the js's from the server on demand, instead of downloading the whole enchilada at the <HEAD/> of the page, right?

thats it. Plus as side effect you'll get a nice separation of your application's logic.

nak1
18 Dec 2008, 5:09 AM
So we're using an implementation of the Broadcast override and we get this intermittent issue where it'll throw an error stating that the subscribe method doesn't exist. It's like the override didn't catch. Any thoughts?

Here's the version we're using


Ext.onReady(function(){

// Register namespace
Ext.namespace('Ext.ux.event');

Ext.override(Ext.util.Observable, {

/**
* This function is <b>addListener</b> analog for broadcasted messages. It accept the same parameters and have the same functionality. For further details please refer to <b>Ext.util.Observable</b> documentation
* @name subscribe
* @methodOf Ext.ux.event.Broadcast
* @param {String} eventName
* @param {Function} fn
* @param {Object} scope
* @param {Object} o
*/
subscribe: function(eventName, fn, scope, o) {
Ext.ux.event.Broadcast.addEvents(eventName);
Ext.ux.event.Broadcast.on(eventName, fn, scope, o);
},


/**
* This function is <b>fireEvent</b> analog for broadcasted messages. It accept the same parameters and have the same functionality. For further details please refer to <b>Ext.util.Observable</b> documentation
* @name publish
* @methodOf Ext.ux.event.Broadcast
* @param {String} eventName
* @param {Object} args Variable number of parameters are passed to handlers
* @return {Boolean} returns false if any of the handlers return false otherwise it returns true
*/
publish : function() {
if(Ext.ux.event.Broadcast.eventsSuspended !== true){
var ce = Ext.ux.event.Broadcast.events ? Ext.ux.event.Broadcast.events[arguments[0].toLowerCase()] : false;
if(typeof ce == "object"){
return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
}
}
return true;
},

/**
* This function is <b>removeListener</b> analog for broadcasted messages.
* @name removeSubscriptionsFor
* @methodOf Ext.ux.event.Broadcast
* @param {String} eventName The type of event which subscriptions will be removed. If this parameter is evaluted to false, then ALL subscriptions for ALL events will be removed.
*/
removeSubscriptionsFor : function(eventName) {
for(var evt in Ext.ux.event.Broadcast.events) {
if ( (evt == eventName) || (!eventName) ) {
if(typeof Ext.ux.event.Broadcast.events[evt] == "object"){
Ext.ux.event.Broadcast.events[evt].clearListeners();
}
}
}
}

});


/**
* This extension provide broadcast capabilites for Ext events system
* It adds 3 new methods to Observable prototype, which mean they can be used with any of its subclasses (panels, windows, formfields etc)
* <br>Examples of usage:
<pre><code>
var w = new Ext.Window({...});
w.subscribe('userlogin', w.redraw, w);

.......

var loginDialog = new Ext.Window({...});

loginDialog.onLoginClick = function (){
....
if ( password == db_password) {
this.publish('userlogin', user_id);
}
};

</code></pre>
* note that in the example above both objects uses their's own scopes to access broadcasting capabilities:
* subscription was made as : <b>w.subscribe</b> and publishing as <b>loginDialog.publish</b>
* <br/><br/>Link to the source code: <a href="http://extjs-ux.org/repo/authors/SamuraiJack/trunk/Ext/ux/event/Broadcast.js">http://extjs-ux.org/repo/authors/SamuraiJack/trunk/Ext/ux/event/Broadcast.js</a>
* <br/>Link to the forum thread: <a href="http://extjs.com/forum/showthread.php?t=37422">http://extjs.com/forum/showthread.php?t=37422</a>
* @class Ext.ux.event.Broadcast
* @extends Ext.util.Observable
*/
Ext.ux.event.Broadcast = new Ext.util.Observable;

}); //eof use

SamuraiJack1
18 Dec 2008, 5:18 AM
The code seems ok, make sure, that when you trying to access "subscribe", Broadcast code was already executed (check the order of <script> tags).

SamuraiJack1
18 Dec 2008, 5:20 AM
Also - you wrapped it into Ext.onReady() - so make sure this call was made before main program Ext.onReady() call

nak1
18 Dec 2008, 6:51 AM
Yeah, the include for the Broadcast.js is above the application code.

I noticed that the error only happens when I do a hard refresh in FireFox. It's almost like the cache is effecting it in somehow.

SamuraiJack1
18 Dec 2008, 7:01 AM
I suggest to remove the Ext.onReady() wrapper - its not required here, since the ux is completely DOM independed. If this will not help - then post here your html header or if possible - a minimal test case, which fires the error.

nak1
18 Dec 2008, 7:11 AM
I'll give that a try. Also I though I'd include the following code as to give you insight where we're calling the subscribe method.



portal.project = Ext.extend(Ext.Component,{
initComponent: function(){
portal.project.superclass.initComponent.call(this);
this.projectid = 0;
this.dsProject = new Array();

this.phaseid = 0;
this.dsPhase = new Array();

this.taskid = 0;
this.dsTask = new Array();

// LISTEN FOR A NEW SYSTEM DATA OF TYPE PROJECT
this.subscribe('newSystemDataID', function(update){

if ( update.type == 'project' ){

this.publish('newProjectID', {'projectid': update.system_dataid});

} else if ( update.type == 'project_phase' ) {

this.publish('updateProjectID', {'projectid': this.projectid, 'isSilent': false});

} else if ( update.type == 'project_task' ) {

this.publish('updatePhaseID', {'projectid': this.phaseid, 'isSilent': false});

}
}, this);

// LISTEN FOR A SELECTED PROJECT FROM THE CAROUSEL
this.subscribe('selectProjectID', function(update){
this.setProject({projectid: update.projectid})
}, this);
})

SamuraiJack1
18 Dec 2008, 7:29 AM
All seems ok, should work.

nak1
18 Dec 2008, 10:02 AM
I wonder if it has something to do with Firebug, I'm using ver 1.2.1 on Firefox 3.0.5. Well, I'll keep hammering at it and see if I can't find out the solution. Thanks.

nak1
19 Dec 2008, 4:43 AM
So it looks like the debugger was the culprit, as it was probably caching files and loading them in some improper order. I've reverted back to Firebug 1.2.0b4, which for now seems to resolve the issue.

yhwh
18 May 2009, 6:05 AM
Hello,
I have added some change to subscribe function, in order to allow auto events removing on container destroy here the code.


Ext.override(Ext.util.Observable, {
subscribe: function(eventName, fn, scope, o) {
Ext.ux.event.Broadcast.addEvents(eventName);
Ext.ux.event.Broadcast.on(eventName, fn, scope, o);
if (this instanceof Ext.Component){
this.on('destroy',function(p){
p.removeSubscriptionsFor(eventName);
},this);
}
}
});

SamuraiJack1
19 May 2009, 12:34 AM
Thanks for fix, will be added in next release. The only note is, that 'removeSubscriptionsFor' will remove all listeners for 'eventName' from singleton Ext.ux.event.Broadcast. Thats why this cleanup should be written as:
Ext.override(Ext.util.Observable, {

subscribe: function(eventName, fn, scope, o) {
Ext.ux.event.Broadcast.addEvents(eventName);
Ext.ux.event.Broadcast.on(eventName, fn, scope, o);

if (this instanceof Ext.Component) this.on('destroy', function() {
Ext.ux.event.Broadcast.removeListener(eventName, fn, scope);
});
}
})

bas_tzx
1 Sep 2010, 12:48 AM
Are you going to make an official new release with this fix? Because today I ran into a problem with a component that had been destroyed and after adding a new one, the event handler was still referring to the old component. Using the 'removeSubscriptionsFor' method didn't seem to fix the problem, but the code above did! :)

BTW, In almost every project I use this plugin. I love the way it decouples components within my applications.

SamuraiJack1
1 Sep 2010, 4:39 AM
Sorry, this plugin is no longer supported.