【问题标题】:Typescript event binding and unbindingTypescript 事件绑定和解除绑定
【发布时间】:2019-01-29 04:59:30
【问题描述】:

我不久前询问过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 中的事件处理程序

【问题讨论】:

    标签: typescript


    【解决方案1】:

    总结您的问题,您尝试使用 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();
    

    玩得开心。

    【讨论】:

    • 我感觉它会涉及代理,但我不知道如何解除绑定,谢谢!快速提问,看看你的 subscribe() 方法,$(window).on("scroll", () => { context.ScrollHandler(context); }); 有什么区别和 $(window).on("scroll", () => context.ScrollHandler(context));
    • 我刚刚遇到了这种方法的问题,因为我无法访问 ScrollHandler 中的事件对象。我怎样才能把它放在那里并且仍然能够解除绑定?
    • 我的意思是滚动事件不是原始对话框打开事件
    • Nvm 我明白了我所要做的就是在处理程序中创建参数并代理自动传递事件。仍然想知道我的第一条评论中两行之间的区别,但如果你有一个分钟
    • Vazgen,它们之间应该没有区别。更喜欢简洁一点的。
    猜你喜欢
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多