2013-01-23 21 views
11

Jest to interfejs jquery od jquery.d.ts:Typescript funkcja obsługi zdarzenia dla pola typu wydarzenie - Nieprawidłowy kontekst

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

To jest mój zwyczaj interfejs naśladując częściową funkcjonalność interfejsu DialogOptions z jquery.d. 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"); 

Ostatnia linia odpala OpenHandler() ale wewnątrz niego, this nie jest typ BaseDialog (inaczej niż w NonEventHandlerMethod).

Powodem muszę funkcję obsługi zdarzenia dla opcji polu dialogowym i powód, dlaczego nie można po prostu to zrobić:

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

jest, bo trzeba dodać dodatkowy obsługi logiki w klasach otwartej imprezę które rozciągają DialogClass i nie ma rozróżnienia między this.member i super.member ... jest tylko rozróżnienie this.function() i 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 
     } 
     ... 
} 

myślę, że może to być błąd ponieważ

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

i wywołanie metody bezpośrednio:

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. 

Odpowiedz

14

maszynopis następuje zwykle JavaScript konwencje scopingu, więc this będą zależne od kontekstu. Jeśli masz metodę na klasie, która strzela na podstawie zdarzenia, celem zdarzenia jest this. Gdy bezpośrednio wywołasz metodę na klasie, klasa zostanie oznaczona jako this.

Jeśli chcesz obejść ten problem, można wykorzystać jak JavaScript podchodzi łańcuch zakres dając this aliasem ...

Oto jeden ze sposobów, aby to zrobić:

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

Składnia funkcji strzałki tworzy alias o nazwie _this w kodzie JavaScript.

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

Akceptujemy sprytnie aliasem wersję this jako parametr i context.someField powinien mieć wartość jesteśmy po.

+2

Jeszcze raz dziękuję, Steve! Byłbym w tyle, bez waszej wielkiej pomocy w kółko. Zaczynam rozumieć to. Mój kod wygląda tak czysty i łatwy w utrzymaniu dzięki Maszynowi, że go kocham! Btw, działało tylko z jawnym podpisem: this.open = (event: Event, ui: DialogUIParams) => {this.OpenHandler (this, event, ui); }; – parliament

Powiązane problemy