13

これはjquery.d.tsのjqueryインターフェースです。

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

これは、jquery.d.tsのDialogOptionsインターフェイスの部分的な機能を模倣したカスタムインターフェイスです。

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.
4

1 に答える 1

14

TypeScript は通常の JavaScript スコープ規則に従うためthis、コンテキストに依存します。イベントに基づいて起動するクラスのメソッドがある場合はthis、イベント ターゲットになります。クラスのメソッドを直接呼び出すと、そのクラスにthisなります。

これを回避したい場合は、JavaScript がthisエイリアスを与えることでスコープチェーンを上っていく方法を利用できます...

これを行う1つの方法は次のとおりです。

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

_thisアロー関数構文は、JavaScriptでエイリアス名を作成します。

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

の巧妙にエイリアスされthisたバージョンをパラメーターとして受け入れ、目的context.someFieldの値を持つ必要があります。

于 2013-01-23T20:31:47.583 に答える