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:
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
}
};
}
|
#
2
|
|
It works the same way.
myElement.on('click',this.handleClick,this,true); Now in handleClick, this will be the execution scope.
|
|
#
3
|
|
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
|
|
#
4
|
|
Ext 1.0 is different and offers more flexibility.
You could use myElement.on({"click": func, scope: this, foo:"bar"});
If no scope is specified, the scope is set to the DOM element.
|
|
#
5
|
|
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]
|
|
#
6
|
|
I'm also no expert on this (
), 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
|
|
#
7
|
|
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
|
|
#
8
| |
|
Quote:
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.
|
|
#
9
|
|
'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
|
|
#
10
|
|
> 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. 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.
|
本文探讨了使用ExtJS框架进行事件处理的不同方式,包括如何利用Ext.select和Ext.on方法为DOM元素绑定事件监听器,并讨论了如何正确设置事件处理函数的作用域及传递额外参数的方法。
), but at least the first two examples make perfect sense.
6563

被折叠的 条评论
为什么被折叠?



