我使用打字稿编写应用程序。并将其编译为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
答案 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;
}
}