3

I'm trying to organize my ExtJS javascript a little better. I've an ExtJS object like this:

Ext.define('QBase.controller.ControlModelConfigurationController', { extend: 'Ext.app.Controller', views: [ 'ControlModelConfiguration' ], init: function() { console.log('Initialized ControlModelConfigurationController'); this.control({ '#testBtn': { click: this.loadModel } }); }, loadModel: function() { console.log('Load Model....'); var conn = new Ext.data.Connection; conn.request({ url: 'partsV10.xml', callback: function(options, success, response) { if (success) { alert("AHHH"); var dq = Ext.DomQuery; var xml = response.responseXML; var nodes = dq.select('part', xml,parent); Ext.Array.forEach(nodes,handleNode); } } }); }, handleNode: function(items) { console.log(item.name); } }); 

The posted code above is not working. Ext.Array.forEach(nodes,handleNode) causes trouble. Instead of using an anonymous function like :

... Ext.Array.forEach(nodes,function(item) { console.log(item)}); } ... 

I'd like to extract the anonymous function as a named external one. Unfortunately I'm unable to figure out the right syntax to establish a code structure as shown above.

Meanwhile, I figured out, that putting

function handleNode(item) { {console.log(item)} } 

at the very end of the file works. Is it possible to make the handleNode method an object - "member" of the controller?

Thanks in advance

Chris

2 Answers 2

4

handleNode is a member of the containing object. When loadModel is called, this contains the right object, but at the time the callback is invoked, it will not point to the one we are interested in. You can save this to the local variable self, and use it instead.

loadModel: function() { var self = this console.log('Load Model....'); var conn = new Ext.data.Connection; conn.request({ url: 'partsV10.xml', callback: function(options, success, response) { if (success) { alert("AHHH"); var dq = Ext.DomQuery; var xml = response.responseXML; var nodes = dq.select('part', xml,parent); Ext.Array.forEach(nodes, self.handleNode); } } }); }, 
Sign up to request clarification or add additional context in comments.

3 Comments

hi vhallac, thank you! Exactly the solution I was looking for. Great!
this answer still, is a solution. But the solution from Rene Saarsoo is more the ExtJS way.
I am not familiar with ExtJS, so I proposed a generic solution. I agree that the other is more in line with ExtJS. :)
2

The solution posted by vhallac is not entirely correct. It assumes that handleNode doesn't reference the current object through this variable. Maybe just a typo, but additionally it's not really the ExtJS way...

Whenever ExtJS provides a callback parameter, there is nearly always a scope parameter to set the value of this within the callback function.

loadModel: function() { console.log('Load Model....'); var conn = new Ext.data.Connection; conn.request({ url: 'partsV10.xml', callback: function(options, success, response) { if (success) { alert("AHHH"); var dq = Ext.DomQuery; var xml = response.responseXML; var nodes = dq.select('part', xml, parent); Ext.Array.forEach(nodes, this.handleNode, this); } }, scope: this }); }, handleNode: function(node) { // From within here you might want to call some other method. // Won't work if you leave out the scope parameter of forEach. this.subroutine(); } 

Just like forEach uses a scope parameter, the request method uses a scope config option. This is ExtJS convention for passing around the scope. You can alternatively create an extra local variable and reference the scope from there, but in the context of ExtJS this style will feel awkward, plus (I'm pretty sure) it's a lot more bug-prone.

1 Comment

hi rene, thanks for the response. You're right this is the more ExtJS way to do it! I've read about the scope parameter but wasn't able to understand the underlying meaning. Now it becomes quite clear. Thanks!!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.