Reputation: 5001
I am trying to set the onclick event handler of an HTMLElement member inside of a class instance but there is a problem with both of my attempts:
class ClassName {
div: HTMLElement;
constructor() {
this.div = document.createElement('div');
this.div.onclick = function(e) {
this._onclick(); // keyword 'this' is not the instance in this scope
}
}
_onclick() {
alert('I've been clicked!');
}
}
class ClassName {
div: HTMLElement;
constructor() {
this.div = document.createElement('div');
this.div.onclick = this._onclick(); // error
}
_onclick() {
alert('I've been clicked!');
}
}
I think this shows a lack of understanding of the language on my part. If someone could please clarify and possibly post a solution it would be greatly appreciated!
Upvotes: 3
Views: 6859
Reputation: 276095
Use arrow notation specific to typescript:
class ClassName {
div: HTMLElement;
constructor() {
this.div = document.createElement('div');
this.div.onclick = (e) => {
this._onclick(); // keyword 'this' is the instance in this scope
}
}
_onclick() {
alert('I've been clicked!');
}
}
()=>
instead of function()
automatically escapes this
for you e.g the following typescript:
class ClassName {
foo = "123";
constructor(){
var x = ()=>{
alert(this.foo);
}
}
}
Generates the following javascript:
var ClassName = (function () {
function ClassName() {
var _this = this;
this.foo = "123";
var x = function () {
alert(_this.foo);
};
}
return ClassName;
})();
Notice var _this = this
which maintains this
using closure inside the function _this.foo
Upvotes: 5
Reputation: 709
The this
keyword is bound to the context in which the function is called.
When the function is called as a result of an event of a DOM element, such as onclick
, it points to that element.
A workaround for your first example is to keep the constructor context in a new variable, which will call that
:
class ClassName {
div: HTMLElement;
constructor() {
this.div = document.createElement('div');
var that = this; //that and this both point to the new Object
this.div.onclick = function(e) {
//this now points elsewhere
that._onclick(); //that still point to the new object
}
}
_onclick() {
alert('I\'ve been clicked!');
}
}
In your second example, you evaluate the onclick
function by adding the parenthesis, so you assign its result to the div.onclick
property.
A correct code is:
class ClassName {
div: HTMLElement;
constructor() {
this.div = document.createElement('div');
this.div.onclick = this._onclick;
}
_onclick() {
alert('I\'ve been clicked!');
}
}
Upvotes: 4