PDA

View Full Version : Passing param and context to onClick?



SteveEisner
12 Nov 2006, 11:18 PM
I keep wanting to have an event handler that accepts a parameter /and/ maintains the scope of its definition... In other words,


getEl('homeButton').on('click', this.mode, (2), this, true);

...

mode: function(ev, arg) { this.displayMode = arg; }


Not sure if that fake code makes it clear, but what I want is for "this" in this.mode to be the same as it was in the init routine which attached the onClick event.

The problem is that it seems I can either specify an additional parameter, OR a parameter that's also the functional scope, but not a parameter plus separate functional scope. I'm kind of curious why the arguments are "param-object, bool" when perhaps "param-object, scope-object" would have been more general purpose? [I haven't looked into the full implementation so perhaps there's a technical reason that the two can't be kept independent...]

I've gotten around this by passing a composite object with "this" and the parameter packaged up together, but am I missing some easier way of doing this?

Animal
13 Nov 2006, 12:18 AM
Your example will work as you want because you passed the last two parameters to on() as this, true.

if you read the docs, that makes the "this" you passed the scope.

If you need to bind a scope to a function, but you atren't going through YAHOO.util.Event.addListener (which is what op() delegates to - RTFM on that), then use the yui-ext extension to the Function object, createDelegate - RTFM on that too!

SteveEisner
13 Nov 2006, 2:00 AM
Sorry, the HTML didn't work, so my example was confusing

What I want is for it to simulate a call to "this.mode(ev, 2)" when the button is clicked. That is, as opposed to "this.mode(ev, this)", which seems like what will happen whenever you pass this,true as the final arguments.

In my example I tried to show the 2 but the bolding failed.

I've noticed that even in Jack's feedviewer example he works around the lack of this kind of parameter passing. For instance when you add a feed it determines the parameters by locating the event target and pulling an ID out of the DOM. Was just wondering if there's an easier way to have it directly call the function with a parameter that is NOT "this" but keeps scope.

From RTFMing it looks like

getEl('homeButton').on('click', this.mode.createDelegate(this, [2], true));
might do what I want.

Animal
13 Nov 2006, 4:23 AM
I think that will do it.

I've begun to use createDelegate instead of the override scope parameter in addListener - it's more obvious than the extra 2 arguments, and allows you to specify arguments in an array (as you have done) as well as scope.

jack.slocum
13 Nov 2006, 5:32 AM
Yep that's the one.

A hidden feature of createDelegate is that the 3rd parameter can also be a number for where to insert the parameter.

For example, when a contentpanel is activated it fires to a handler that looks like this (supposing part of an object):

onActivated : function(panel){
},

Suppose you wanted to have an id passed first:

panel.on('activate', this.onActivated.createDelegate(this, ['panel-foo'], 0);

Then your handler could be:

onActivated : function(fooId, panel){
},

Ok not a great example (I'm tired I been writing regular expressions all night), but you can see what I mean.