Asher G.
Asher G.

Reputation: 5001

Set the onclick property of a HTMLElement member in a class to a method of the same class

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:

1: keyword this can't be used

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!');
  }
}

2: Error:'Cannot convert 'void' to (ev:FocusEvent) => any.'

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

Answers (2)

basarat
basarat

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

corentin
corentin

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

Related Questions