简体   繁体   English

从具有事件侦听器的对象调用函数

[英]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 .问题是当 clickHandler 事件被触发时,这个对象等于CANVAS对象,而不是 RemixView So I get an error that says:所以我收到一条错误消息:

this.getHoveredObject is not a function this.getHoveredObject 不是函数

What is correct approach at that stuation?在那种情况下正确的方法是什么?

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:通常的方法是为回调使用一个简单的闭包,并在闭包可以引用的局部变量中捕获this的适当值:

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):您还可以使用Function.prototype.bind来创建绑定函数(如user123444555621所做的那样):

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 :或者,如果你想使用 ES6,你可以使用箭头函数

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

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.请注意,这可能不适用于旧版浏览器,但有适用于这些浏览器的polyfill

Make prototype a function.使prototype成为一个函数。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM