2014-05-17 17 views
15

Sto provando a creare una direttiva AngularJS utilizzando TypeScript. La mia direttiva richiede 'ngModel' e sto anche usando un servizio personalizzato inserito nella mia direttiva. Il mio problema principale è che il mio servizio non può essere utilizzato all'interno della mia funzione di collegamento.AngularJS Funzione di collegamento direttiva TypeScript

Ecco un esempio di quello che sto cercando di realizzare:

module app.directives { 

    export var directiveName: string = "theDirective"; 

    angular.module("myApp").directive(directiveName, 
      (myFactory: app.services.MyFactory) => 
      { 
       return new MyDirective(myFactory); 
      }); 

    export interface IMyDirectiveScope extends ng.IScope { 
     ngModel: ng.INgModelController; 
    } 

    export class MyDirective implements ng.IDirective { 

     restrict = "A"; 
     require = "ngModel"; 
     scope = { 
      ngModel:'=' 
     } 

     constructor(private myFactory: app.services.MyFactory) { 

     } 


     link(scope: IMyDirectiveScope , elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) { 
      //this is window here 

      elem.bind('blur', (evt: JQueryEventObject) => { 
       //keyword this is also window here, so yeah bummer indeed 
       validate(); 
      }); 

      function validate() { 
       //I need to use my factory here, but I can seem to get it. 
       //this is always window and I'm kinda stuck here 
      } 
     } 
    } 
} 

io non riesco a trovare un po 'di cose più avanzate su questo argomento. Tutti gli esempi che non trovo non sembrano utilizzare servizi o una complessa funzione di collegamento. Si prega di rispondere a questa domanda con qualche sorta di esempio. È un inganno che tu pensi.

Aggiornamento: Il fatto che "questo" all'interno della mia funzione di collegamento sia finestra e non "MyDirective" non ha molto senso per me. Qualche idea sul perché sarebbe?

risposta

16

Le classi funzionano in modo ottimale per controller e controller di direttive, ma non credo che ne utilizzerei uno per l'intera direttiva. Ma se si vuole si sarebbe probabilmente hanno a che fare qualcosa di simile:

export class MyDirective implements ng.IDirective { 

    public link; 

    restrict = "A"; 
    require = "ngModel"; 
    scope = { 
     ngModel:'=' 
    } 

    constructor(private myFactory: app.services.MyFactory) { 
     this.link = this.unboundLink.bind(this); 
    } 


    unboundLink(scope: IMyDirectiveScope , elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) { 
     //Now you should be able to access myFactory 
     this.myFactory.doSomething(); 

     elem.bind('blur', (evt: JQueryEventObject) => { 
      //keyword this is also window here, so yeah bummer indeed 
      validate(); 
     }); 

     function validate() { 
      //I need to use my factory here, but I can seem to get it. 
      //this is always window and I'm kinda stuck here 
     } 
    } 
} 

EDIT: Senza una classe che si potrebbe fare qualcosa di simile:

angular.module("myApp").directive("theDirective", 
    function(myFactory: app.services.MyFactory) { 
     return { 
      restrict: 'A', 
      require: 'ngModel', 
      scope: {'ngModel': '='}, 
      link: function(scope: IMyDirectiveScope , elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) { 
       //You can access myFactory like this. 
       myFactory.doSomething(); 
      } 
     } 
    } 
); 
+0

Th questo funziona, potresti darmi un esempio di come ti avvicineresti a questo tipo di situazioni senza una lezione? – user1613512

+0

@ user1613512 Ho modificato la mia risposta per includere un esempio senza una classe – rob

+0

Write unboundLink (...) {var self = this; ...} allora puoi usare la variabile autonoma all'interno di validate() invece di questa. –

21

Utilizzando le classi e di ereditare da ng.IDirective è la strada da percorrere con TypeScript.

dattiloscritto include il supporto per la funzione di grasso freccia () => da EcmaScript 6. E 'una sintassi abbreviata che cambia anche il modo in cui la parola chiave this funziona:

class MyDirective implements ng.IDirective { 
    restrict = 'A'; 
    require = 'ngModel'; 
    scope = { 
     ngModel: '=' 
    } 

    constructor(private myFactory: app.services.MyFactory) { 
    } 

    link = (scope: IMyDirectiveScope, elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) => { 
     console.log(this); // this points to MyDirective instance instead of Window 

     elem.bind('blur', (evt: JQueryEventObject) => { 
      console.log(this); // this points to MyDirective instance instead of Window 
      this.validate(); 
     }); 
    } 

    validate() { 
     console.log(this); // this points to MyDirective instance instead of Window 
    } 


    static factory(): ng.IDirectiveFactory { 
     var directive = (myFactory: app.services.MyFactory) => new MyDirective(myFactory); 
     directive.$inject = ['myFactory']; 
     return directive; 
    } 
} 

app.directive('mydirective', MyDirective.factory()); 

Si può anche contare sulla vecchia moda var self = this; modello:

class MyDirective implements ng.IDirective { 
    restrict = 'A'; 
    require = 'ngModel'; 
    scope = { 
     ngModel: '=' 
    } 

    constructor(private myFactory: app.services.MyFactory) { 
    } 

    link = (scope: IMyDirectiveScope, elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) => { 
     console.log(this); // this points to MyDirective instance instead of Window 

     var self = this; 

     function validate() { 
      console.log(self); // self points to MyDirective instance 
     } 

     elem.bind('blur', function(evt: JQueryEventObject) { 
      console.log(self); // self points to MyDirective instance 
      validate(); 
     }); 
    } 
} 

risposta correlati: https://stackoverflow.com/a/29223535/990356

+0

dove è definito questo tipo di IMyDirectiveScope? e per l'app.services.MyFactory qual è la sua definizione? – Oscar

+0

@Oscar dovresti leggere prima la domanda: 'interface IMyDirectiveScope estende ng.IScope' –

+0

Possiamo farlo senza usare la funzione link? Sto usando Angular 1.4 e poiché protetteremo il nostro codice su Angular 2.0 e le funzioni di collegamento non sono supportate lì, non voglio scrivere questa logica usando la funzione di collegamento .. Quindi, per favore fammi sapere se è possibile accedere all'elemento senza la funzione di collegamento. – ATHER

Problemi correlati