2013-01-23 21 views
11

यह jquery.d.ts से एक jQuery इंटरफेस है। 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() आग लेकिन इसके अंदर, thisBaseDialog (NonEventHandlerMethod में विपरीत) टाइप नहीं है।

कारण मैं संवाद विकल्प फ़ील्ड के लिए एक ईवेंट हैंडलर समारोह और कारण है कि मैं बस यह नहीं कर सकता की जरूरत है:

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

क्योंकि मैं अतिरिक्त खुले घटना कक्षाओं में तर्क से निपटने जोड़ने की जरूरत है

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

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

      //Additional handling logic 
     } 
     ... 
} 

मैं यह एक बग हो सकता है लगता है: कि DialogClass का विस्तार करने और वहाँ this.member और super.member के बीच कोई भेदभाव है ... वहाँ this.function के बीच केवल भेदभाव() और super.function() है क्योंकि

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

टाइपप्रति सामान्य जावास्क्रिप्ट scoping सम्मेलनों इस प्रकार है, इसलिए this संदर्भ पर निर्भर हो जाएगा। यदि आपके पास किसी ऐसी कक्षा पर कोई विधि है जो किसी ईवेंट के आधार पर आग लगती है, तो this ईवेंट लक्ष्य होगा। जब आप सीधे कक्षा पर कोई विधि कॉल करते हैं, तो this कक्षा होगी।

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

आप इस के आसपास प्राप्त करना चाहते हैं, तो आप कैसे जावास्क्रिप्ट this दे रही है एक उपनाम द्वारा गुंजाइश श्रृंखला चलता है का लाभ ले सकते ...

यहाँ एक तरीका है कि ऐसा करने के लिए है

तीर-फ़ंक्शन सिंटैक्स जावास्क्रिप्ट में _this नाम और उपनाम का नाम बनाता है।

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

हम this एक पैरामीटर के रूप और context.someField की चतुराई से एलियास संस्करण को स्वीकार मूल्य हम के बाद कर रहे हैं होना चाहिए।

+2

धन्यवाद, स्टीव! मैं आपकी सारी बड़ी मदद के बिना पीछे रहूंगा। इस के लटकने के लिए शुरू करना। मेरा कोड टाइपस्क्रिप्ट के साथ इतना साफ और रखरखाव दिखता है, मैं इसे प्यार करता हूँ! बीटीडब्ल्यू, यह केवल स्पष्ट हस्ताक्षर के साथ काम करता है: this.open = (घटना: घटना, ui: DialogUIParams) => {this.OpenHandler (यह, घटना, ui); }; – parliament

संबंधित मुद्दे