jQuery 劫持 TypeScript 的 'this' 引用

标签 jquery typescript

我在我的 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 的值相关联。

另一个不太理想的选择是 thatself 的经典用法:

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/

相关文章:

node.js - 在 firebase 中看不到请求 header 的值?

jquery - 使用 JQuery Page Scroller 的 100% 高度 div

php - ajax POST 操作成功后数据库中没有任何反应

node.js - 在 typescript 中找不到 'autobind-decorator' 的声明文件

javascript - 单击时自动聚焦 ng-multiselect-dropdown 的 Filterfield

Typescript 继承并重载了函数的字符串文字参数

javascript - jQuery:$.ajaxSetup(beforeSend) 和 $(document).ajaxSend 之间有什么区别吗?

javascript - 使用 jQuery 的轮播

javascript - 计算字符串长度,包括 'invisible characters' 就像 javascript 和 php 中的\r\n

typescript - 在 Typescript 和 Expo 中使用 require 时获取 "Invalid call"