2015-06-12 32 views
6

Wydaje się, że istnieje wiele sposobów tworzenia dyrektyw Angular w języku TypeScript. Najchętniej widziałem, jak używać statycznej funkcji fabrycznej:Zastrzyki zależne od dyrektywy kątowej - TypeScript

module app { 
    export class myDirective implements ng.IDirective { 
     restrict: string = "E"; 
     replace: boolean = true; 
     templateUrl: string = "my-directive.html"; 

     link: ng.IDirectiveLinkFn = (scope: ng.IScope, el: ng.IAugmentedJQuery, attrs: ng.IAttributes) => { 
     }; 

     static factory(): ng.IDirectiveFactory { 
      var directive: ng.IDirectiveFactory =() => new myDirective(); 
      return directive; 
     } 
    } 

    angular.module("app") 
     .directive("myDirective", myDirective.factory()); 
} 

Ale nie jestem pewien, co zrobić, jeśli muszę coś wstrzyknąć. Chciałbym powiedzieć $ timeout:

module app { 
    export class myDirective implements ng.IDirective { 
     restrict: string = "E"; 
     replace: boolean = true; 
     templateUrl: string = "my-directive.html"; 

     constructor(private $timeout: ng.ITimeoutService) { 
     } 

     link: ng.IDirectiveLinkFn = (scope: ng.IScope, el: ng.IAugmentedJQuery, attrs: ng.IAttributes) => { 
      // using $timeout 
      this.$timeout(function(): void { 
      }, 2000); 
     } 

     static factory(): ng.IDirectiveFactory { 
      var directive: ng.IDirectiveFactory =() => new myDirective(); // Uhoh! - What's goes here? 
      directive.$inject = ["$timeout"]; 
      return directive; 
     } 
    } 

    angular.module("app") 
     .directive("myDirective", myDirective.factory()); 
} 

Jak widać powyżej, nie jestem pewien, jak nazywają myDirective contructor i przechodzą w $ timeout.

+0

Czemu nakładania własnych modułów na szczycie kątowe? Jakie korzyści daje dodatkowa warstwa złożoności, dodatkowy stan globalny i duplikacja semantyczna ?. – yangmillstheory

Odpowiedz

4

Wystarczy podać $timeout jako argument funkcji konstruktora fabryki i przekazać go.

static factory(): ng.IDirectiveFactory { 
     var directive: ng.IDirectiveFactory = 
         ($timeout:ng.ITimeoutService) => new myDirective($timeout); 
     directive.$inject = ["$timeout"]; 
     return directive; 
    } 
+1

To proste! Dzięki! – user888734

+0

@ user888734 Nie ma za co. :) – PSL

+0

Nie mogłem tego zrobić bez twojej pomocy, dziękuję – deadManN

0

Chociaż nie jest akceptowane odpowiedź chciałbym dać moje dwa centy .. Jakiś czas temu miałem ten sam problem z dyrektywy, ale również z filtrami (czyli kątowe rejestrów z fabryki filtrów), więc postanowił zbudować małą bibliotekę wokół standardowych definicji typów, które pozwoliły mi napisać coś takiego (kontrolowane i kod szablonu jest pominięta):

@Directive('userRank') 
export class UserRankDirective implements ng.IDirective { 

    controller = UserRankDirectiveController; 
    restrict = 'A'; 
    template = template; 
    //controllerAs: 'ctrl', set as default 
    replace = true; 
    scope = { 
     user: '=userRank' 
    } 

    constructor($q: ng.IQService) { 
     console.log('Q service in UserRankDirective:', $q); 
    } 

} 

aby było to możliwe musiałem dostosować kod maszynopis emiter i teraz tworzy metadane interfejsu (że ng.IQService jest dostępne w środowisku wykonawczym i mapowane do '$q' w tablicy konstruktorów); metadane są używane przez dekorator @Directive, który rejestruje dyrektywę w module aplikacji pod numerem this code. Możesz rzucić okiem na przykładowy kod aplikacji here.

0

I w obliczu tego samego problemu i rozwiązać go poprzez wdrożenie klasy Util nazwie „ComponentRegistrator” (zainspirowany komentarzach on this page):

/// <reference path="../../../Typings/tsd.d.ts"/> 
module Common.Utils { 
    "use strict"; 

    export class ComponentRegistrator { 
     public static regService(app: ng.IModule, name: string, classType: Function) { 
      return app.service(name, classType); 
     } 

     public static regController(app: ng.IModule, name: string, classType: Function) { 
      var factory: Function = Component.reg(app, classType); 
      return app.controller(name, factory); 
     } 

     public static regDirective(app: ng.IModule, name: string, classType: Function) { 
      var factory: Function = Component.reg(app, classType); 
      return app.directive(name, <ng.IDirectiveFactory>factory); 
     } 

     private static reg<T extends ng.IDirective>(app: ng.IModule, classType: Function) { 
      var factory: Function = (...args: any[]): T => { 
       var o = {}; 
       classType.apply(o, args) || console.error("Return in ctor missing!"); 
       return <T> o; 
      }; 
      factory.$inject = classType.$inject || []; 
      return factory; 
     } 
    } 
} 

a to może na przykład zostać wykorzystane w następujący sposób:

/// <reference path="../../../Typings/tsd.d.ts"/> 
///<reference path="../../Common/Utils/Component.ts"/> 

module Sample { 
    "use strict"; 

    class SampleDirective implements ng.IDirective { 
     public static $inject: string[] = []; 

     public templateUrl: string; 
     public scope: {}; 
     public restrict: string; 
     public require: string; 
     public link: ng.IDirectiveLinkFn; 

     constructor() { 
      this.templateUrl = "/directives/sampleDirective.html"; 
      this.restrict = "A"; 
      this.scope = { 
       element: "=", 
      }; 
      this.link = this.linker; 
      return this; // important! 
     } 

     private linker = (scope: IExpressionConsoleScope): void => { 
      // ... 
     }; 
    } 

    ComponentRegistrator.regDirective(app, "directiveName", SampleDirective); 
} 

Zanotować return this w construcotor i static $inject. Trzeba by określić wstrzyknąć opisany przez PSL:

// ... 
class SampleDirective implements ng.IDirective { 
    public static $inject: string[] = ["$timeout"]; 
// ... 
constructor(private $timeout:ng.ITimeoutService) { 
// ... 

ten sposób powielanie metody fabryki można uniknąć i zawsze można użyć tego samego wzoru ...

0

Trochę prostsze, moim zdaniem:

export var SomeComponent = ($timeout: any): ng.IDirective => { 
 
    return { 
 
    controller, 
 
    controllerAs: 'vm', 
 
    restrict: 'E', 
 
    templateUrl: 'components/someTemplate/someTemplate.html', 
 
    scope: { 
 
     someAttribute: '@' 
 
    }, 
 
    link: { 
 
     post: (scope, elem, attr, ctrl) => { 
 
     console.log('Should see this here:', $timeout); 
 
     } 
 
    } 
 
    }; 
 
} 
 

 
SomeComponent.$inject = ['$timeout'];

Powiązane problemy