4

前段时间我问过这个问题,关于将 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 中的事件处理程序

4

1 回答 1

6

总结您的问题,您尝试使用 jQuery 来挂钩(和取消挂钩)DOM 元素上的事件,但您希望事件处理程序的“this”上下文指向包含事件处理程序的类。

There are multiple ways to solve this.

First, you can use 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);
   }
}

Another option would be to use RxJS, which allows you to treat 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();

Have fun.

于 2013-02-20T23:28:35.620 回答