Javscript scope and event handlers
Hi all,
I think I am probably doing something wrong, and would be grateful for any advice.
I have a 'class' that looks something like this:
function MyClass() {
this.myFunction = function() {
// Some code here.
}
this.myOtherFunction = function() {
// Some more code here.
}
}
which I use like this:
var myThing = new MyClass();
myThing.myFunction();
in 'myFunction' I add an event listener to an animation (although it could be anything), which references 'myOtherFunction':
this.myFunction = function() {
// Some code here.
someAnimation.addEventListener('complete', this.myOtherFunction);
}
This all works fine. However, when 'myOtherFunction' is called the context has changed (to that of the animation I think?), so 'this' no longer refers to the original instance of myClass. Is it possible to do this in such a way that myOtherFunction is 'aware' of the original context?
In this particular case I can get around it, in that myThing is effectively global, but this seems less than optimal.
Any advice would be greatly appreciated! I realise this isn't a strictly Titanium-based query, but figured it's almost certainly something others have run into. My Javascript knowledge is is not as developed as it could be!
Thanks,
Toby
2 Answers
-
I'm having the same kind of problem. My class object is going out of scope and I cant work out why.
I have a GUI class that constructs a form. The Form has a button that fires an event to open a new window in the current tab. The new window is created via another class and this new window/class collects user input and stores it as instance variables that can be accessed from the first window… The instance variables are fine inside the second class but come back blank when access from outside the class.
Here is some code.class 1
function searchTable() { this.mode = 'buy'; this.sub = ''; this.ssubs = false; this.minPrice = ''; this.maxPrice = ''; this.getPriceRow = function() { // Create row var row = Ti.UI.createTableViewRow({ height: 40, backgroundColor: '#ffffff', hasChild: true, // Add arrow to right of row selectionStyle: Titanium.UI.iPhone.TableViewCellSelectionStyle.NONE }); // Create label var label = Ti.UI.createLabel({ text: 'Price Range', top: 10, left: 10, height: 'auto', color: '#000000', textAlign: 'left', font: { fontSize: 15 } }); // Create range var range = Ti.UI.createLabel({ text: 'Any', top: 10, right: 10, height: 'auto', color: '#6d6e71', textAlign: 'right', font: { fontSize: 15 } }); // Set price range row.addEventListener('click', function(e) { var prt = new priceRangeTable(); var table = prt.getTable(); // Create button var button = Ti.UI.createButton({ title:'Done', width: 200, height: 35, left: 'auto', right: 'auto', bottom: 5, enabled: true, style: Ti.UI.iPhone.SystemButtonStyle.BORDERED }); // Close window button.addEventListener('click', function(e) { this.minPrice = prt.minPrice; this.maxPrice = prt.maxPrice; alert(this.minPrice); alert(this.maxPrice); if(this.minPrice != '' && this.maxPrice != '') { range.text = this.minPrice + ' - ' + this.maxPrice; } else if(this.minPrice != '') { range.text = this.minPrice + ' - Any'; } else if(this.maxPrice != '') { range.text = 'Any - ' + this.maxPrice; } else { range.text = 'Any'; } window.close(); }); }
Class 2
function priceRangeTable() { this.minPrice = ''; this.maxPrice = ''; this.getMinPriceRow = function() { // Create row var row = Ti.UI.createTableViewRow({ height: 'auto', backgroundColor: '#ffffff', selectionStyle: Titanium.UI.iPhone.TableViewCellSelectionStyle.NONE }); // Create label var label = Ti.UI.createLabel({ text: 'Min Price', top: 5, left: 5, height: 'auto', color: '#000000', textAlign: 'left', font: { fontSize: 15 } }); // Create input var input = Ti.UI.createTextField({ color: '#000000', top: 0, right: 5, height: 35, width: 200, hintText: 'Any', clearButtonMode: 1, // Show clear button borderStyle: Titanium.UI.INPUT_BORDERSTYLE_NONE, keyboardType: Titanium.UI.KEYBOARD_NUMBER_PAD }); // Set min price value input.addEventListener('blur', function(e) { this.minPrice = e.source.value; }); row.add(label); row.add(input); return row; } this.getMaxPriceRow = function() { // Create row var row = Ti.UI.createTableViewRow({ height: 'auto', backgroundColor: '#ffffff', selectionStyle: Titanium.UI.iPhone.TableViewCellSelectionStyle.NONE }); // Create label var label = Ti.UI.createLabel({ text: 'Max Price', top: 5, left: 5, height: 'auto', color: '#000000', textAlign: 'left', font: { fontSize: 15 } }); var input = Ti.UI.createTextField({ color: '#000000', top: 0, right: 5, height: 35, width: 200, hintText: 'Any', clearButtonMode: 1, // Show clear button borderStyle: Titanium.UI.INPUT_BORDERSTYLE_NONE, keyboardType: Titanium.UI.KEYBOARD_NUMBER_PAD }); // Set max price value input.addEventListener('blur', function(e) { this.maxPrice = e.source.value; }); row.add(label); row.add(input); return row; } }
Can anyone help? Its probably some simple coding error but I can't seem to work it out.
-
What you need to do is pass the context of your class into the object that listening for an event:
this.myFunction = function() { // Some code here. someAnimation.parent = this; someAnimation.addEventListener('complete', function(e) { e.source.parent.myOtherFunction(); // Ps. it might be: this.parent.myOtherFunction(); }); }