Typescript事件绑定和解绑

时间:2013-02-20 21:15:01

标签: typescript

前一段时间我问过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中的事件处理程序

1 个答案:

答案 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();

玩得开心。