前一段时间我问过this question有关将jquery事件委托给typescript类中的事件处理程序方法的问题。答案是使用以下模式
public class LoginDialog {
...
constructor() {
//this.open = this.OpenHandler; //Incorrect way
this.open = (event: Event, ui: DialogUIParams) => { //Correct way
this.OpenHandler(this, event, ui);
};
...
}
public OpenHandler(context: LoginDialog, event: Event, ui: DialogUIParams) {
//Use context as "this"
}
...
}
但是,现在我处于类似的情况,我需要在将来的某个时间删除处理程序但由于匿名函数而无法执行:
public class LoginDialog {
...
constructor() {
this.open = (event: Event, ui: DialogUIParams) => {
this.OpenHandler(this, event, ui);
};
this.close = (event: Event, ui: DialogUIParams) => {
this.CloseHandler(this, event, ui);
}
...
}
public OpenHandler(context: LoginDialog, event: Event, ui: DialogUIParams) {
$(window).on("scroll", () => { context.ScrollHandler(context); });
//$(window).on("scroll", context.ScrollHandler(context)); //Never gets called
//$(window).on("scroll", context.ScrollHandler); //this = window
}
public CloseHandler(context: LoginDialog, event: Event, ui: DialogUIParams) {
$(window).off("scroll", () => { context.ScrollHandler(context); }); //Does not remove
}
public ScrollHandler(context: Interfaces.IBaseDialog) {
context.jQueryDialog.dialog("option", "position", "center");
...
}
...
}
在这种情况下,on
绑定中没有箭头语法,我的ResizeOrScrollHandler
永远不会被调用,但是使用它我无法删除CloseHandler中的事件处理程序
答案 0 :(得分:6)
总结一下你的问题,你试图使用jQuery来挂钩(和取消)一个DOM元素上的事件,但是你希望事件处理程序的'this'上下文指向包含事件处理程序的类。
有多种方法可以解决这个问题。
首先,您可以使用jQuery.proxy
class LoginDialog {
public OpenHandler(context: LoginDialog, event: Event, ui: DialogUIParams) {
$(window).on("scroll", $.proxy(context.ScrollHandler, context));
}
public CloseHandler(context: LoginDialog, event: Event, ui: DialogUIParams) {
$(window).off("scroll", context.ScrollHandler);
}
}
另一种选择是使用RxJS,这可以让您对events like disposable objects进行处理:
var scrollSubscription = $(window)
.onAsObservable("scroll")
.subscribe(() => console.log("this == the containing class!"));
...
// When we're done, just call .dispose.
scrollSubscription.dispose();
玩得开心。