PDA

View Full Version : Problem with Custom Events



cjharrelson
21 Jun 2007, 5:02 PM
I am extending a the TreeLoader and trying to add a custom event:


TreeLoaderAccounts = function(config) {

this.baseParams = {};
config.requestMethod = 'GET';
Ext.apply(this, config);
TreeLoaderAccounts.superclass.constructor.call(this, config);

this.addEvents({
'nodeclicked': true
});
};

Ext.extend(TreeLoaderAccounts, Ext.tree.TreeLoader, {

processResponse: function(response, node, callback)
{
...

child.on( 'click', function(node){ this.fireEvent('nodeclicked', node); } );

...
}
});

var acctTreeLoader = new TreeLoaderAccounts( {dataUrl:'../getTreeData'} )
cashFlowTreeLoader.on('nodeclicked', function()
{
alert('nodeclicked');
});


This is not working. I get no alert. The data is being returned and teh tree is rendered. The fireEvent method must be returning true as the node does highlight.

Any help is much appreciated!

cjharrelson
3 Jul 2007, 4:36 AM
I figured out that it is not syntax causing an issue. If I move the this.fireEvent(...) call to outside of the child.on(...) method, it works. So it appears that there is an issue firing an event from within another event. Or possible firing one objects event from within another object's event. Is it a scoping problem. Does this not refer to my containing object when I am inside of another object's event handler?

Can someone please help me with this?

tobiu
3 Jul 2007, 4:47 AM
hi cjharrelson,

i am just working on a similar problem,
maybe this links helps a bit:

http://extjs.com/deploy/ext/docs/output/Ext.View.html



var store = new Ext.data.Store(...);

var view = new Ext.View("my-element",
'<div id="{0}">{2} - {1}</div>', // auto create template
{
singleSelect: true,
selectedClass: "ydataview-selected",
store: store
});

// listen for node click?
view.on("click", function(vw, index, node, e){
alert('Node "' + node.id + '" at index: ' + index + " was clicked.");
});

// load XML data
dataModel.load("foobar.xml");

jack.slocum
9 Jul 2007, 2:42 AM
That scope parameter you have probably seen quite a few times in the documentation is what your code is missing. The scope you pass, refers to the object you want to be this in the called function. So, in your code you have:

child.on( 'click', function(node){ this.fireEvent('nodeclicked', node); } );

Since you haven't passed a scope to the handler, this within the anonymous function you have defined as your handler will default to whatever the default this is. In your case, it would be the node that was actually clicked. If you modify your code slightly to pass the scope you want, this inside the anonymous function will point to your loader class:

child.on( 'click', function(node){ this.fireEvent('nodeclicked', node); }, this );

cjharrelson
13 Jul 2007, 12:26 PM
Jack, I had tried what you suggested to no success. Your explanation made me test to see what 'this' was when I set things up like you suggested. It was the 'window' object. This is where all of my trouble was stemming from.

I was using prototype's .each() method to iterate my array instead of a for loop. I like the each() method due to its elegance and readability.

When I changed to a for loop, 'this' was referencing the object I was inside of. :D After some more testing, as soon as I entered the each closure, 'this' became 'Window.' I did not feel like debugging prototype anymore, so I abandoned the each method.

If I get some time, I want to figure out if there is a bug in prototype, or if I was using the each() method incorrectly, but for now, on with coding. If anyone knows why I was seeing this behavior, please chime in.