如何将eventhandler绑定到typescript中的类方法?

时间:2016-08-14 08:36:43

标签: jquery events typescript binding

我使用打字稿编写应用程序。并将其编译为js,除了事件绑定部分外,它运行良好。 _stateService是我注入此类的类。

以下类尝试使用jQuery创建DOM元素,然后将其传递给另一个类进行渲染,创建部分运行良好并最终在页面上呈现。但事件绑定有点棘手。

首先,我想使用$()。click()来绑定,但由于元素尚未渲染而失败。

然后我尝试使用$()。on()来绑定,它可以工作。但在运行时,它会抛出一个错误:

  

TemplatingService.ts:37未捕获的TypeError:无法读取属性   未定义的'CallBack'(匿名函数)@   TemplatingService.ts:37dispatch @jquery.min.js:3q.handle @   jquery.min.js:3

似乎如果我只是在绑定函数中使用console.log(“test”),它就可以了。但是如果我尝试将它绑定到类方法,它就失败了。似乎失去了背景,我该如何解决这个问题?

原始打字稿是:

export class TemplatingService implements ITemplatingService {
    _stateService: IStateService;

    constructor(stateService: IStateService) {
        this._stateService = stateService;
    }

    createPage(page:IPage):JQuery{
        let outerDiv = this.createLayout();
        for (let element of page.rawLayout){
            switch(element.type){
                case "button":
                    let temp = this.createJQueryButton();
                    $(".emulator").on('click', "#"+element.name, function(){
                                   this._stateService.CallBack(element);
                    });
                    outerDiv.append(temp);
                    break;
            }
        }
        return outerDiv;
    }
}

相关的生成js如下所示:

"use strict";
var TemplatingService = (function () {
    function TemplatingService(stateService) {
        this._stateService = stateService;
    }

    TemplatingService.prototype.createPage = function (page) {
        var outerDiv = this.createLayout();
        var _loop_1 = function(element1) {
            switch (element.type) {
                case "button":
                    var temp = this_1.createjQueryButton();
                    $(".emulator").on('click', "#" + element.name, function () {
                        this._stateService.CallBack(element);
                    });
                    outerDiv.append(temp);
                    break;
            }
        };
        var this_1 = this;
       for (var _a = 0, _b = page.rawLayout; _a < _b.length; _a++) {
            var element1 = _b[_a];
            _loop_1(element1);
        }
        return outerDiv;

}());

exports.TemplatingService = TemplatingService;
//# sourceMappingURL=TemplatingService.js.map

2 个答案:

答案 0 :(得分:1)

您需要绑定this才能进行回调。

 $(".emulator").on('click', "#"+element.name, function(){
     this._stateService.CallBack(element);
 }.bind(this));

或更好的解决方案是将this保存到变量

createPage(page:IPage):JQuery{
    const self = this;
    let outerDiv = this.createLayout();
    for (let element of page.rawLayout){
        switch(element.type){
            case "button":
                let temp = this.createJQueryButton();
                $(".emulator").on('click', "#"+element.name, function(){
                     self._stateService.CallBack(element);
                });
                outerDiv.append(temp);
                break;
        }
    }
    return outerDiv;
}

答案 1 :(得分:1)

问题确实是您传递给.on的函数有自己的this上下文。使用普通的ES5,您可以使用.bind(this)var self = this;来“修复”this上下文,但使用TypeScript和ES6,您也可以使用箭头功能:

export class TemplatingService implements ITemplatingService {
    _stateService: IStateService;

    constructor(stateService: IStateService) {
        this._stateService = stateService;
    }

    createPage(page:IPage):JQuery{
        let outerDiv = this.createLayout();
        for (let element of page.rawLayout){
            switch(element.type){
                case "button":
                    let temp = this.createJQueryButton();
                    $(".emulator").on('click', "#"+element.name, () => { // <<< arrow!
                                   this._stateService.CallBack(element);
                    });
                    outerDiv.append(temp);
                    break;
            }
        }
        return outerDiv;
    }
}