我在我的 TypeScript 类中使用 jQuery。
export class RedTextBox {
private element : HTMLInputElement;
private changed : Boolean;
Attach(textbox : HTMLInputElement) {
this.element = textbox;
ChangeColor();
}
ChangeColor() {
$(this.element).css("background", "red");
$(this.element).on("change", function() {
this.Changed = true; // 'this' here is not the object of Typescript
});
}
}
在上面的代码中,我收到一条错误消息,提示 this.Changed
未定义。我检查了调试器,发现在 jQuery 事件中,“this”实际上是 HTML 元素而不是 TypeScript 对象。是否有替代的“this”,或者我们可以强制 jQuery 单独保留“this”(没有双关语意)?
最佳答案
当您使用 function
定义匿名函数时,它的 this
未绑定(bind)到您定义它的实例,jQuery 利用 call
/apply
在这些回调中为 this
赋值。
最简单的解决方案是换成箭头函数:
$(this.element).on("change", () => {
this.Changed = true;
});
当你定义一个箭头函数时,箭头函数内部的 this
的值与函数定义范围内的 this
的值相关联。
另一个不太理想的选择是 that
或 self
的经典用法:
const self = this;
$(this.element).on("change", function() {
self.Changed = true;
});
编辑
最后一点,如果你已经有一个函数并且不能使用上述选项之一来访问外部范围的上下文,你可以强制 this
成为你想要的内部范围使用 Function.prototype.bind
的函数。如果您的事件处理程序/回调是类的成员,则此示例最相关。
ChangeColor() {
$(this.element).on("change", this.HandleChange.bind(this))
}
HandleChange() {
this.Changed = true;
}
这只适用于对 bind
的调用,如果您忘记绑定(bind)它,那么您最终会遇到与开始时相同的问题。此外,像这样即时绑定(bind)的成本很高,因为每次调用 bind
时都必须创建一个新函数。因此,通常您会预先绑定(bind)在构造函数中分发的函数。
class RedTextBox {
constructor() {
this.HandleChange = this.HandleChange.bind(this);
}
ChangeColor() {
$(this.element).on("change", this.HandleChange);
}
HandleChange() {
this.Changed = true;
}
}
请注意我如何在构造函数中只绑定(bind)一次,然后将引用自由传递给 this.HandleChange
作为回调。
关于jQuery 劫持 TypeScript 的 'this' 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51898682/