2013-01-23 22 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

相關問題