Reputation: 370
developing under Titanium I have encountred this strange behaviour with OOP JavaScript and event handler scope. This is my code:
MyClass = function()
{
this.var1 = '50';
this.button = Ti.UI.createButton({
...
});
this.button.parentRef = this;
this.button.addEventListener('click', function(e){
var self = e.source.parentRef;
console.log(self.var1);
console.log(self.var2);
});
this.var2 = 'Test';
...
/* this.button is then added to a view */
};
...
var c = new MyClass();
...
When I click on the button, in my console I would expect to find:
50
Test
But actually the result is:
50
<null>
If I move the assignment
this.var2 = 'Test'
before the
this.button.addEventListener
statement, the result is:
50
Test
Sounds like that the this.button.parentRef = this assignment is by copy and not by reference...
What is the cause of this behavior ?
Upvotes: 4
Views: 271
Reputation: 6095
You are correct.
What you are doing has wrinkles with Titanium, whenever you add an attribute to a Titanium native object, it is passed by value, as the underlying object (your view) is actually a native mapped to a JavaScript object. So what happens is that the current value of that object (in your case this
) is sent across the Javascript-to-native bridge and set as a property of the native object (or something like that).
What it comes down to is that, any attributes on a native object you set are pretty much cloned by the object, thats why you are seeing the above functionality.
So what are some ways to deal with this?
This is the easy way:
var self = this;
this.button.addEventListener('click', function(e){
console.log(self.var1);
console.log(self.var2);
});
It somewhat pollutes your button listener scope, but at least its not in global scope.
Upvotes: 6