2013-01-23 45 views
11

这是jquery.d.ts一个jQuery接口:打字稿事件处理函数 - 不正确的情况下

export interface IDialogEvent extends DialogEvent { 
    (event: Event, ui: DialogUIParams): void; 
} 

这是我的自定义界面模仿jquery.d的DialogOptions界面的部分功能。 TS:

export interface IDialogOptions { 
    open: IDialogEvent; 
} 

export class DialogClass implements IDialogOptions { 

    //Dialog options 
    public open: IDialogEvent; 

    //Class related fields 
    public someField: any; 
    public dialogEl: JQuery; 

    constructor() { 
     this.open = this.OpenHandler; 
     this.dialogEl = $("<div></div>").dialog(this); 
     //Passing "this" initializes the dialog by mapping relevant class fields 
     //to the dialog's "option" object, in this case the only "relevant" field is "open". 
    } 

    public OpenHandler(event: Event, ui: DialogUIParams) { 
     var value = this.someField; //BAD. "this" is not type BaseClass 
    } 

    public NonEventHandlerMethod() { 
     var value = this.someField; //GOOD. "this" is type BaseClass 
    } 
} 

var dialog = new DialogClass(); 
dialog.dialogEl.dialog("open"); 

最后一行触发OpenHandler()但它里面,this不是类型BaseDialog(不像NonEventHandlerMethod)。

我需要在对话框选项字段的事件处理函数,为什么我不能简单地做到这一点的原因的原因:

export class DialogClass implements IDialogOptions { 
    ... 
     constructor() { 
      this.open =() => { 
       //event handling logic 
      }; 
      ... 
     } 
     ... 
}   

是因为我需要添加额外的开放式事件类处理逻辑扩展DialogClass并有this.member和super.member之间没有区别......有this.function之间()super.function)仅分化和(:

export class LoginDialog extends DialogClass { 
    ... 
     constructor() { 
      this.open = this.OpenHandler; 
      ... 
     } 

     public OpenHandler(event: Event, ui: DialogUIParams) { 
      super.OpenHandler(); //Base handling logic 

      //Additional handling logic 
     } 
     ... 
} 

我觉得这可能是一个错误因为

export class DialogClass implements IDialogOptions { 
    ... 
     constructor() { 
      this.open =() => { 
       var test = this.someField; //Correct context 
      }; 
      ... 
     } 
     ... 
    } 

和直接调用方法:

var dialog = new DialogClass(); 
    dialog.OpenHandler(); //Correct context when called directly 
    //Note: I haven't actually tested this persay but this function is no different 
    //than any other functionso a direct call should certainly not be problem. 

回答

14

打字稿遵循通常的JavaScript作用域公约,所以this将取决于上下文。如果您在基于某个事件触发的课程上有方法,则this将成为活动目标。当你直接调用某个班的方法时,this将成为班级。

如果要解决这个问题,你可以利用JavaScript的是如何通过给this别名走到作用域链...

这里是做的一个方法:

this.open =() => { this.OpenHandler(this); }; 

箭头函数语法在JavaScript中创建并别名_this

public OpenHandler(context: DialogClass, event: Event, ui: DialogUIParams) { 
    var value = context.someField; 
} 

我们接受的this作为参数,context.someField巧妙化名版本应该有我们追求的价值。

+2

再次感谢史蒂夫!如果没有你们一次又一次的大力帮助,我会落后的。开始了解这一点。我的代码看起来很干净,可以用Typescript维护,我喜欢它!顺便说一句,它只能用明确的签名:this.open =(event:Event,ui:DialogUIParams)=> {this.OpenHandler(this,event,ui); }; – parliament

相关问题