| Page 1 of 1 | [ 3 posts ] |
|
I want to define a set of events such that:
1) Listeners can be notified whether or not the listeners were set before or after the event has been fired. 2) Listeners can be set in separate YUI() instances. Looking at the API, it seems that EventTarget with the options fireOnce=true, broadcast=2 will do the trick. However, I saw some behavior that I was not quite expecting. Here's my test code: Code: (function () { var eventLogger = function ( Y, modName, evtName, when, pub ) { var eType; pub.on( evtName, function(e) { eType = e ? e.type : 'undef'; Y.log( 'in ' + modName + ': eventType "' + eType + '" fired, sub ' + when + ' firing, via pub.on()' ); }); Y.on( evtName, function(e) { eType = e ? e.type : 'undef'; Y.log( 'in ' + modName + ': eventType "' + eType + '" fired, sub ' + when + ' firing, via Y.on()'); }); Y.Global.on( evtName, function(e) { eType = e ? e.type : 'undef'; Y.log( 'in ' + modName + ': eventType "' + eType + '" fired, sub ' + when + ' firing, via Y.Global.on()'); }); }; YUI.add( 'emod01', function(Y) { var modName = 'emod01'; var evtName = 'evt01'; var pub = new Y.EventTarget(); pub.name = modName; eventLogger( Y, modName, evtName, 'before', pub ); pub.publish( evtName, { fireOnce: true, broadcast: 2, // 1=inst level, 2=global level emitFacade: true // emit a facade so we get the event target }); pub.fire( evtName ); eventLogger( Y, modName, evtName, 'after ', pub ); }); // YUI.add( YUI().use( 'event-custom', 'dump', function (Y) { Y.use( 'emod01' ); }); })(); // end immed func Here the results logged in console: Code: in emod01: eventType "evt01" fired, sub before firing, via pub.on() in emod01: eventType "evt01" fired, sub before firing, via Y.on() in emod01: eventType "evt01" fired, sub before firing, via Y.Global.on() in emod01: eventType "evt01" fired, sub after firing, via pub.on() When the listeners are set before the event is fired, everything worked as expected. But when they are set after the event has fired, only pub.on(..) (the EventTarget instance which published and fired the event) was notified. Is this the way it's meant to work? I guess the workaround for me would be to define a singleton EventTarget instance to be shared among all the modules on the page. Would this be the right way? |
|
After further investigation, I seem to be able to achieve what I want by publishing and firing with Y.Global. Here's a simplified version of my test code:
Code: (function () { var MyEvtName = 'MyEvent'; // This instance set up listeners BEFORE the event is fired YUI().use( 'event-custom', function(Y) { Y.on( MyEvtName, function(e) { Y.log( 'recv event "' + e.type + '", subscribed before firing, via Y.on()'); }); Y.Global.on( MyEvtName, function(e) { Y.log( 'recv event "' + e.type + '", subscribed before firing, via Y.Global.on()'); }); }); YUI().use( 'event-custom', function(Y) { Y.Global.publish( MyEvtName, { fireOnce: true, broadcast: 2, // 1=inst level, 2=global level emitFacade: true // emit a facade so we get the event target }); Y.Global.fire( MyEvtName ); }); // This instance set up listeners AFTER the event is fired YUI().use( 'event-custom', function(Y) { Y.on( MyEvtName, function(e) { Y.log( 'recv event "' + e.type + '", subscribed after firing, via Y.on()'); }); Y.Global.on( MyEvtName, function(e) { Y.log( 'recv event "' + e.type + '", subscribed after firing, via Y.Global.on()'); }); }); })(); These are my results shown on console: Code: recv event "MyEvent", subscribed before firing, via Y.Global.on() recv event "MyEvent", subscribed before firing, via Y.on() recv event "MyEvent", subscribed after firing, via Y.Global.on() Would this be the right way to go? That is, is it OK to use Y.Global.publish(..) to publish my event and then use Y.Global.fire(...) to fire it or are there some gotchas that I am not aware of? Also, in my tinkering I've encountered that error condition when not setting fireOnce to true and setting broadcast to 2. That is, if I publish my event as such: Code: Y.Global.publish( MyEvtName, { //fireOnce: true, broadcast: 2, // 1=inst level, 2=global level emitFacade: true // emit a facade so we get the event target }); My script crashed with the following error in Chrome: Code: Uncaught RangeError: Maximum call stack size exceeded n.error yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:9 n.use.F yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:8 n.use.E yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:8 d.Loader._finish yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader._onSuccess yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader.loadNext yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:22 d.Loader._insert yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader._insert._internalCallback yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader.loadNext yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:22 d.Loader._insert yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader._insert yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader.insert yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader._continue yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader._finish yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader._onSuccess yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader.loadNext yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:22 d.Loader.loadNext.S yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 d.Loader.loadNext.I yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:21 a.Get.i yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:10 a.Get.h yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:10 a.Get.j.E.onload yui.yahooapi.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js:10 A similar error occured in Firefox. Both browsers are the latest version. Is this something I need to worry? |
|
Yes, it is safe to publish on Y.Global, but you don't want to set the broadcast flag for these events. That recursion error is a bug, but not unexpected.
Your original approach should have worked, so that looks like a separate bug. |
| Page 1 of 1 | [ 3 posts ] |
| You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum |
© 2006-2013 Yahoo! Inc. All rights reserved.
All code on this site is licensed under the BSD License unless stated otherwise.
About This Site · Security Contact Info
Powered by phpBB® Forum Software © phpBB Group