[ 3 posts ]

dkdkhk

  • Username: dkdkhk
  • Joined: Sun Dec 19, 2010 3:48 pm
  • Posts: 2
  • Offline
  • Profile

Custom event notification after it's fired...

Post Posted: Sun Dec 19, 2010 5:23 pm
+0-
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?

dkdkhk

  • Username: dkdkhk
  • Joined: Sun Dec 19, 2010 3:48 pm
  • Posts: 2
  • Offline
  • Profile

Re: Custom event notification after it's fired...

Post Posted: Mon Dec 20, 2010 12:42 pm
+0-
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?

Adam Moore

YUI Contributor

  • Username: adam
  • Joined: Wed Sep 03, 2008 11:16 am
  • Posts: 356
  • GitHub: apm
  • Gists: apm
  • Offline
  • Profile

Re: Custom event notification after it's fired...

Post Posted: Mon Dec 20, 2010 1:13 pm
+0-
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.
  [ 3 posts ]
Display posts from previous:  Sort by  
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