天天看点

passing object into addListener - Ext JS

DomQuery is great. I figured I'd clean up some of my code with it until I ran into this problem:

I have an object that attaches one of it's own functions to a bunch of dom elements. When that function executes it calls another of its functions.

batchInit is really selecting the appropriate item and then assign the function to call and a reference to the object so when the function get's executed it has a reference to the object.

I can replace the entire batchInit function with:

Ext.select("#wrap span.ui-info a:first-child").on("click", this.prepInfo);

Which is amazing. However, I don't understand how to pass the object to the function itself as in the old addListener:

YAHOO.util.Event.addListener(anchors[0],'click', func,

this

, false);

so that the prepInfo knows how to call the

showDialog

function.

Perhaps I'm doing this all wrong...martin

The old way:

var InfoDialog = function(){
    // define some private variables
    var dialog;
    
    // return a public interface
    return {
        init : function(){
        	this.batchInit("ui-info", this.prepInfo);
                //more init functions here
        },
        
		batchInit : function(type, func){
			 var links = YAHOO.util.Dom.getElementsByClassName(type, "", "wrap");
				 
			 // attach to click event of anchor and pass the link into the dialog box when called
			 for (var i = 0; i<links.length;i++) {
				if (links[i].tagName == "SPAN") {
					var anchors = links[i].getElementsByTagName('a');
					YAHOO.util.Event.addListener(anchors[0],'click', func, this, false);
				}
			 }
		},

		prepInfo : function(e, el){
                        dialog.setTitle('Info');
			Ext.apply(dialog, {modal:false});
			el.showDialog(e, this);
		},
		
		showDialog : function(e, link){ 
			//do some work
        }
    };
}      
passing object into addListener - Ext JS
  # 2  
passing object into addListener - Ext JS
02-21-2007, 10:11 PM
passing object into addListener - Ext JS

It works the same way.

myElement.on('click',this.handleClick,this,true);

Now in handleClick, this will be the execution scope.

passing object into addListener - Ext JS
  # 3  
passing object into addListener - Ext JS
02-21-2007, 10:24 PM
passing object into addListener - Ext JS

I see. There is a slight diference though>

With Ext.on the objects in the called functions reversed:

YAHOO's addlistener assignes the clicked link to 'this' and the passed object to 'el'. Ext.on however sets 'this' to the object and el to the link clicked...martin

passing object into addListener - Ext JS
  # 4  
passing object into addListener - Ext JS
02-22-2007, 02:40 AM
passing object into addListener - Ext JS

Ext 1.0 is different and offers more flexibility.

You could use

myElement.on({"click": func, scope: this, foo:"bar"});      

The function will be called with params (Ext.EventObject, targetEl, {"click": func, scope: this, foo:"bar"}) in the scope specified by the "scope" property. The options object passed to the on() call is passed as the 3rd parameter, so you can add anything you want in there, and pick it up in your handler.

If no scope is specified, the scope is set to the DOM element.

passing object into addListener - Ext JS
  # 5  
passing object into addListener - Ext JS
02-22-2007, 09:00 PM
passing object into addListener - Ext JS

That's cool that you can pass in other parameters and such, but I don't understand why the object changes that 'this' refers to. It's incosistent:

Ext.select("span.ui-info a:first-child").on("click",this.prepInfo);

When the prepInfo function fires: 'this' refers to the link itself and oddly enough is also passed in as the third parameter (the second being the click event). arguments.length = 3.

Ext.select("span.ui-info a:first-child").on("click",this.prepInfo, this);

When the prepInfo function fires: 'this' suddenly no longer refers to the link itself but the additional object passed in. The third parameter is now the link. In essence its flipped.

Ext.select("span.ui-info a:first-child").on({"click": this.prepInfo, scope: this});

When the prepInfo function fires: 'this' again no longer refers to the link itself but the additional object passed in. In addition a new object is attached with the click event and the object in it.

Same result with

Ext.select("span.ui-info a:first-child").on("click",this.prepInfo, {scope: this});

I'd call it a bug, but I'm really not an expert on this.

At least in the first three situations 'this' inside the attached function should refer to the object the function is attached to and not the object the function belongs to and the additional parameter should be the third one (I hope this makes sense)...martin

[/code]

passing object into addListener - Ext JS
  # 6  
passing object into addListener - Ext JS
02-22-2007, 09:24 PM
passing object into addListener - Ext JS
I'm also no expert on this (
passing object into addListener - Ext JS

), but at least the first two examples make perfect sense.

this.prepInfo only identifies the function, it does not define or imply the scope in any way, that's the job of the third parameter of on. If that is omitted, the scope defaults to the element the handler is attached to.

As I'm mostly a C++/Java guy this concept is also pretty alien to me, but after watching the yahoo yui tutorial vids linked elsewhere in this forum, I at least learned to recognize when JavaScript's weirdness strikes :p

passing object into addListener - Ext JS
  # 7  
passing object into addListener - Ext JS
02-22-2007, 09:51 PM
passing object into addListener - Ext JS

This however sounds like an API issue and not a javascript weirdness and hence a question for Jack?

I would think the API should be consistent. It would also be consistent with the addlistener arguments order in the YUI, I think or at least how I've used it)...martin

passing object into addListener - Ext JS
  # 8  
passing object into addListener - Ext JS
02-22-2007, 10:05 PM
passing object into addListener - Ext JS
Quote:

Originally Posted by martin This however sounds like an API issue and not a javascript weirdness and hence a question for Jack?

I would think the API should be consistent. It would also be consistent with the addlistener arguments order in the YUI, I think or at least how I've used it)...martin

I don't think it's any different really. Ext also has a addListener thing if you feel more comfortable with that. With Ext and on, you're already saying which element to use and thus it doesn't need to be passed. However, if you want to change the scope, then you can pass an object in and pass true at the end. The same works for YUI. on is sort of like myobj.addClickListener(); in that it's just shorthand for addListener.

There's also that fact that Jack is trying to free Ext from dependencies on YUI, so there's no reason it has to follow the YUI API.

passing object into addListener - Ext JS
  # 9  
passing object into addListener - Ext JS
02-22-2007, 10:55 PM
passing object into addListener - Ext JS

'on' is just shorthand for 'addListener' according to the docs.

My struggle is not that the element is passed automatically, but that the behavior changes in the different ways of calling 'on' or 'addlistener'.

That makes it hard to deal with the various implementations if i later need to pass a scope or other variable, I have to change the called function as well.

I guess I'll have to think again about using it. I'd rather know that its consistent and I can make changes later without having to rewrite the functions again.

Thanks for your insights...martin

passing object into addListener - Ext JS
  # 10  
passing object into addListener - Ext JS
02-23-2007, 04:58 AM
passing object into addListener - Ext JS

> That's cool that you can pass in other parameters and such, but I don't understand

> why the object changes that 'this' refers to.

The parameter is called "scope" because that is what it changes.

> It's incosistent:

The event handlers are very consistent. If you pass in a scope - that becomes the scope - otherwise the scope is the event element. Let's look at your examples.

Ext.select("span.ui-info a:first-child").on("click",this.prepInfo);

No scope passed, so scope is the link.

Ext.select("span.ui-info a:first-child").on("click",this.prepInfo, this);

Ext.select("span.ui-info a:first-child").on({"click": this.prepInfo, scope: this});

Scope passed is "this", so that will be the scope on handler calls (not the link).

> I'd call it a bug, but I'm really not an expert on this.

I would take the time to get to learn them. I promise, I don't do things for no reason.

passing object into addListener - Ext JS

The new event API is mostly backwards compatible, but offers much more flexibility and power.

> At least in the first three situations 'this' inside the attached function should

> refer to the object the function is attached to and not the object the function

> belongs to and the additional parameter should be the third one

"this" inside the function is the scope. So if you pass in a requested scope, it is set to that. How can this be wrong? It gives you the ability to point "this" at anything you want, and if you say I want it to be X it should set it to X and not leave it the link.

Your handlers are always called with 3 parameters:

e (Ext.EventObject), target (The event target, e.g. the link), options (the options object passed in to the event attachment).

If you have any other questions, I'd be happy to help.

passing object into addListener - Ext JS

继续阅读