PDA

View Full Version : Why 'this' points to different type of objects?



g2mac
15 Jan 2010, 12:25 AM
Hello!

I'm confusing with 'this' inside .on() handler.
Here is my code:

Ext.get(Ext.query('select',myFormNode)[0]).on('change',function(){
console.log(this)
});
Here this is ExtJS Object.

Ext.select('input',myFormNode).on('keydown',function(){
console.log(this)
});
And here this is HTML Object.
Why?

danh2000
15 Jan 2010, 12:28 AM
Because the 2 different methods you are using return different things:

Look at the return type for Ext.query and Ext.select in the docs - select returns a CompositeElement while query returns an array of Dom nodes.

Also, look at the scope param to addListener (on).

g2mac
15 Jan 2010, 12:41 AM
But anyway before .on we have ExtObject.
In first case Ext.get() returns Ext.Element and in the second Ext.select() returns Ext.CompositeElement and anyway an event catches a HTMLElement, so why inside function(){} this is not only a HTMLElement or not only a Ext.Element?

danh2000
15 Jan 2010, 12:50 AM
Use the third param to specify scope and force this to be what you want.

Animal
15 Jan 2010, 1:17 AM
But anyway before .on we have ExtObject.
In first case Ext.get() returns Ext.Element and in the second Ext.select() returns Ext.CompositeElement and anyway an event catches a HTMLElement, so why inside function(){} this is not only a HTMLElement or not only a Ext.Element?

It's not a CompositeElement. It's a CompositeElementLite.

The difference is that a CompositeElement maintains an Array of Ext.Elements, and so that WOULD give you an Ext.Element in your handler.

But Ext Core does not have the CompositeElement class, it has the CompositeElementLite class, and I think that has a bug.

try



Ext.override(Ext.CompositeElementLite, {
addListener : function(eventName, handler, scope, opt){
var els = this.elements,
len = els.length,
i, e;

for(i = 0; i<len; i++) {
if(e = els[i]) {
Ext.EventManager.on(e, eventName, handler, scope || me.getElement(e), opt);
}
}
return this;
}
});



That uses the shared flyweight Element as the "this" reference, not an HTML element.

If that works for you, then I think I'll submit this as a Bug Report.

g2mac
15 Jan 2010, 3:06 AM
But with or without your override I get HTMLElement inside my handler.

Animal
15 Jan 2010, 3:20 AM
Did you continue to use "on"??

The override only overrides addListener!

Animal
15 Jan 2010, 3:21 AM
And the code needs to be



Ext.override(Ext.CompositeElementLite, {

// Only need this prior to 3.1!
getElement : function(el){
// Set the shared flyweight dom property to the current element
var e = this.el;
e.dom = el;
e.id = el.id;
return e;
},

addListener : function(eventName, handler, scope, opt){
var me = this,
els = me.elements,
len = els.length,
i, e;

for(i = 0; i<len; i++) {
if(e = els[i]) {
Ext.EventManager.on(e, eventName, handler, scope || me.getElement(e), opt);
}
}
return me;
}
});

g2mac
15 Jan 2010, 6:23 AM
Yes, I was using 'on'.
addListener works good.
But why 'on' isn't just a wrapper for 'addListener'? So I need to override both methods.

Condor
15 Jan 2010, 6:37 AM
No, 'on' still points to the old 'addListener' implementation.

You need:

Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;

g2mac
15 Jan 2010, 6:51 AM
Oh, yes, exactly, I have lost sight of prototype ))
Thanks!