Mirat Can Bayrak
Mirat Can Bayrak

Reputation: 651

Calling function from an object with event listener

I have a view model something like this:

CANVAS = getElementById...

RemixView = function(attrs) {
     this.model = attrs.model;
     this.dragging = false;
     this.init();
};

RemixView.prototype = {
    init: function() {
        CANVAS.addEventListener("click", this.handleClick);
    },
    handleClick: function(ev) {
        var obj = this.getHoveredObject(ev);
    },
    getHoveredObject: function(ev) {}
    ...
    ...
}
rv = new RemixView()

the problem is my when clickHandler event fired, this object is being equal to CANVAS object, not RemixView. So I get an error that says:

this.getHoveredObject is not a function

What is correct approach at that stuation?

Upvotes: 1

Views: 5014

Answers (3)

mu is too short
mu is too short

Reputation: 434585

The usual approach is to use a simple closure for the callback and capture the appropriate value of this in a local variable that the closure can reference:

RemixView.prototype = {
    init: function(this) {
        var _this = this;
        CANVAS.addEventListener("click", function(ev) {
            return _this.handleClick(ev);
        });
    },
    //...
};

You could also use Function.prototype.bind to make a bound function (as user123444555621 does):

RemixView.prototype = {
    init: function(this) {
        CANVAS.addEventListener("click", this.handleClick.bind(this));
    },
    //...
};

Or, if you want to use ES6, you could use an arrow function:

RemixView.prototype = {
    init: function(this) {
        CANVAS.addEventListener("click", ev => this.handleClick(ev));
    },
    //...
};

Upvotes: 4

pete
pete

Reputation: 25081

Make prototype a function.

RemixView.prototype = function () {
    init: function() {
        CANVAS.addEventListener("click", this.handleClick);
    },
    handleClick: function(ev) {
        var obj = this.getHoveredObject(ev);
    } ///...
//...
}

Upvotes: 0

user123444555621
user123444555621

Reputation: 152956

You want to bind the handler function:

CANVAS.addEventListener("click", this.handleClick.bind(this));

Note that this may not work in older browsers, but there are polyfills for those.

Upvotes: 1

Related Questions