[ 9 posts ]

Steven Olmsted

YUI Contributor

  • Username: solmsted
  • Joined: Wed Apr 14, 2010 1:47 pm
  • Posts: 82
  • Location: Richmond, VA
  • GitHub: solmsted
  • Gists: solmsted
  • IRC: solmsted
  • Offline
  • Profile

Custom Event Arguments

Post Posted: Sat Sep 03, 2011 11:57 am
+0-
This was something I found very strange when I began working with YUI 3. Arguments passed to a custom event do some sort of mix with the event façade.

Here's the documentation: http://yuilibrary.com/yui/docs/api/clas ... ethod_fire

If the first argument is an object literal and the event is configured to emit an event façade, the event façade will replace that parameter after the properties the object literal contains are copied to the event façade.

Does this seem weird to anyone else? Why would I want my arguments to get garbled with the event façade?

I don't have many custom events which accept arguments, but when I do I always have to code around this. I insert an empty object so my real arguments don't get mixed.

Code:
myObject.fire('eventName', {}, arg1, arg2, arg3);


Then I can easily listen to the event:

Code:
myObject.on('eventName', function (eventFacade, arg1, arg2, arg3) {
    // do stuff
});


This feature doesn't make sense to me so I'm just wondering if I'm missing something. What do people use this for?

Juan Ignacio Dopazo

YUI Contributor

  • Username: jdopazo
  • Joined: Fri Oct 02, 2009 5:39 am
  • Posts: 637
  • Location: Buenos Aires, Argentina
  • Twitter: juandopazo
  • GitHub: juandopazo
  • Gists: juandopazo
  • Offline
  • Profile

Re: Custom Event Arguments

Post Posted: Sat Sep 03, 2011 3:09 pm
+0-
We use it because that way we deal with custom events the same way we deal with DOM events. DOM events send data through the Event object, like e.keyCode. It makes sense to use the same pattern.

Also, I find it similar to the question of using an object as a way of passing multiple parameters. I always prefer to use an object because I'm better at remembering parameter names than parameter order.

Steven Olmsted

YUI Contributor

  • Username: solmsted
  • Joined: Wed Apr 14, 2010 1:47 pm
  • Posts: 82
  • Location: Richmond, VA
  • GitHub: solmsted
  • Gists: solmsted
  • IRC: solmsted
  • Offline
  • Profile

Re: Custom Event Arguments

Post Posted: Mon Sep 05, 2011 7:30 am
+0-
Okay, I can see that. I usually use custom events in a very different way from DOM events so it hadn't occurred to me to try to mimic them.

I agree about passing objects around instead of individual arguments.

I usually follow a pattern something like this:

Code:
myObject.on('myEvent', function (eventFacade, eventObject) {
    // Do Stuff
}, this);

myObject.fire('myEvent', {}, {
    argName1: 'stuff',
    argName2: 'more stuff'
});


That has been working out quite well. I just have to remember the extra {}.

Juan Ignacio Dopazo

YUI Contributor

  • Username: jdopazo
  • Joined: Fri Oct 02, 2009 5:39 am
  • Posts: 637
  • Location: Buenos Aires, Argentina
  • Twitter: juandopazo
  • GitHub: juandopazo
  • Gists: juandopazo
  • Offline
  • Profile
Tags:

Re: Custom Event Arguments

Post Posted: Mon Sep 05, 2011 7:40 am
+0-
The idea behind the EventFacade is to do exactly that. Don't be afraid of overwriting anything important in it. Chances of doing that are very slim.

As for events defined by yourself, you can chose not to use an EventFacade.
Code:
function MyVeryOwnClass() {
  this.publish('myevent', {
    emitFacade: false
  });
}

Steven Olmsted

YUI Contributor

  • Username: solmsted
  • Joined: Wed Apr 14, 2010 1:47 pm
  • Posts: 82
  • Location: Richmond, VA
  • GitHub: solmsted
  • Gists: solmsted
  • IRC: solmsted
  • Offline
  • Profile

Re: Custom Event Arguments

Post Posted: Tue Sep 06, 2011 11:17 am
+0-
In most of my custom event handlers I ignore the eventFacade object; I don't frequently need it. I'm not afraid of copying over its properties but I am afraid of its properties contaminating my data. Here's a made up example:

Suppose my object, which extends base, has some function which requests data of a web service through jsonp. When the response comes in, a 'response' event is fired on my object. If the jsonp response object was passed as a parameter, it suddenly gets extra properties added to it when the event handler receives it. This isn't good when my event handler is expecting a clean response object.

I see two fairly simple ways to overcome this. The first is the way I described above, by passing an empty object as the 2nd parameter to fire. The 2nd is to wrap the response in a new object like

{response: responseObject}

then this new response property will be available on the eventFacade.

I've been using the first way because it happened to be the first thing I thought of the first time I realized my event data was getting mixed in with extra properties.

I just now started a jsFiddle so I could test what happens either way when emitFacade is turned on or off. I published events 'a' and 'b'. I gave them both the same defaultFn which spat out its arguments. For 'a' I set emitFacade: true and for 'b' I set emitFacade: false. Then I fired both events and passed along an object of stuff as the 2nd argument.

The first thing I discovered, it seemed like 'b' wasn't getting fired. The common defaultFn only ran once. I tested by trying: .on('b', defaultFn) and that worked, the arguments were unexpectedly very different, and it took me a moment to figure this out.

The api docs for eventTarget.publish say that emitFacade defaults to false. I don't frequently use the eventFacade, so I usually omit this parameter and let it default to false. When I first tried out YUI 3's custom events, I did this and it worked. I never had any big need to enable facades. I've been copying this pattern ever since.

In my jsFiddle, I specifically set emitFacade to false and it works very different from what I've seen in my other projects. Are the docs wrong? Has emitFacade been defaulting to true on all my events?

If that's the case, this is a silly thing for me not to have noticed all this time. Now I'll need to adjust my way of thinking when it comes to custom events. I am glad I posted my little design decision question. I was thinking event facades were only useful when bubbling or broadcasting the event. I use default functions frequently.

Luke Smith

YUI Contributor

  • Username: lsmith
  • Joined: Thu Aug 28, 2008 7:50 am
  • Posts: 514
  • Location: Sunnyvale
  • Twitter: ls_n
  • GitHub: lsmith
  • Gists: lsmith
  • IRC: ls_n
  • YUI Developer
  • Offline
  • Profile
Tags:

Re: Custom Event Arguments

Post Posted: Tue Sep 06, 2011 2:03 pm
+0-
Right. defaultFn is linked to emitFacade. emitFacade is actually a trigger that makes events go down the "advanced" route in the fire() lifecycle. non-emitFacade events also don't bubble.
http://yuilibrary.com/yui/docs/event-cu ... -lifecycle

I'd say the typical, or even recommended, way of passing data along with events is to do what you have as your 2nd option--fire('foo', {response: responseObject}). This preserves the pattern of "callback is passed an event object that hosts payload as properties", so even if the event is configured with emitFacade: false, the callback will receive an object that can be named e.

Another option you have if you're paranoid (not necessarily in a bad way) about the event properties being overwritten by the event system is to use e.details[0].
http://yuilibrary.com/yui/docs/api/clas ... ty_details

I'll be adding to the custom event and EventTarget docs over time. The details property will get some doc love.

Juan Ignacio Dopazo

YUI Contributor

  • Username: jdopazo
  • Joined: Fri Oct 02, 2009 5:39 am
  • Posts: 637
  • Location: Buenos Aires, Argentina
  • Twitter: juandopazo
  • GitHub: juandopazo
  • Gists: juandopazo
  • Offline
  • Profile

Re: Custom Event Arguments

Post Posted: Tue Sep 06, 2011 3:35 pm
+0-
solmsted wrote:
I am glad I posted my little design decision question.

Indeed! I learned something too.

Steven Olmsted

YUI Contributor

  • Username: solmsted
  • Joined: Wed Apr 14, 2010 1:47 pm
  • Posts: 82
  • Location: Richmond, VA
  • GitHub: solmsted
  • Gists: solmsted
  • IRC: solmsted
  • Offline
  • Profile

Re: Custom Event Arguments

Post Posted: Wed Sep 07, 2011 11:14 am
+0-
I figured out the source of my confusion. I made a ticket for the API documentation but I didn't reply here.

The API documentation for EventTarget.publish and Attribute.publish say that emitFacade defaults to false. This is incorrect, emitFacade actually defaults to the value of the emitFacade config property passed into the constructor of EventTarget. This config property does default to false.

The default false in these API docs is generally correct for when someone instantiates or augments EventTarget directly. These API docs fail to mention that Attribute instantiates EventTarget and passes emitFacade: true to its constructor.

For every object which augments Attribute or extends Base, the publish method will default the emitFacade property to true. This isn't clear in the API docs, and there is only one small reference to it in EventTarget's user guide.

Here is a link to the ticket I made: http://yuilibrary.com/projects/yui3/ticket/2531057
I tried to be specific and not just say: Make better docs.

Luke Smith

YUI Contributor

  • Username: lsmith
  • Joined: Thu Aug 28, 2008 7:50 am
  • Posts: 514
  • Location: Sunnyvale
  • Twitter: ls_n
  • GitHub: lsmith
  • Gists: lsmith
  • IRC: ls_n
  • YUI Developer
  • Offline
  • Profile

Re: Custom Event Arguments

Post Posted: Wed Sep 07, 2011 1:54 pm
+0-
I appreciate the ticket. I'll have to think about the best way to handle it, though. The Attribute API doc link you included has the publish method because it's inherited from EventTarget. So those are EventTarget's method docs showing, which as you noted, are only appropriate for some of the configuration properties.

If I changed the ET API docs, it would likely have to include the removal of default values, which is seldom a good thing for API docs. Otherwise, new API docs would need to be written in Attribute's source to indicate different behavior, but such would need to happen for every class that directly extends or is augmented with EventTarget. That would be a maintenance nightmare if EventTarget should change.

I'll think on it. Let me know in the ticket if you think of some better language.
  [ 9 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
cron