Angularjs directive injection using typescript

Say I have a simple angular directive that looks like this:

app.directive('setFocus', ['$timeout', function($timeout) { return { restrict: 'AC', link: function(_scope, _element) { $timeout(function() { _element[0].focus(); }, 0); } }; }]); 

How can I write this using Typescript and get the $ timeout available in the link function? My example would look something like this:

 /// <reference path="../../reference.ts"/> class SetFocus{ constructor() { var directive: ng.IDirective = {}; directive.restrict = 'EA'; directive.scope = { }; directive.link= function ($scope, $element, $attrs) { // How can I access $timeout here? } return directive; } } directives.directive('setFocus', [SetFocus]); 

This may be a stupid example, but it is a principle that I would like to get while working using nested dependencies in angular reference functions.

+6
source share
2 answers

Try as follows:

 class SetFocus implements ng.IDirective { //Directive settings restrict :string = 'EA'; scope : any= {}; //Take timeout argument in the constructor constructor(private $timeout: ng.ITimeoutService) { } link: ng.IDirectiveLinkFn = ($scope: ng.IScope, $element: ng.IAugmentedJQuery, $attrs: ng.IAttributes) => { //refer to the timeout this.$timeout(function() { $element[0].focus(); }, 0); } //Expose a static func so that it can be used to register directive. static factory(): ng.IDirectiveFactory { //Create factory function which when invoked with dependencies by //angular will return newed up instance passing the timeout argument var directive: ng.IDirectiveFactory = ($timeout:ng.ITimeoutService) => new SetFocus($timeout); //directive injection list directive.$inject = ["$timeout"]; return directive; } } directives.directive('setFocus', SetFocus.factory()); 

It may be a problem with the way you have it right now. Since the factory directive is not updated, therefore its constructor will execute with this as a global object. That way, you also won't have a huge constructor, and you can write it properly.

If you have many dependencies introduced instead of repeating the arguments in the factory, you can also:

  var directive: ng.IDirectiveFactory = (...args) => new (SetFocus.bind.apply(SetFocus, [null].concat(args))); 
+9
source

To avoid all factory templates (and the constructor array in general), I recently wrote a small library (currently as a test project) that simplifies the definition of directives (the controller and template that are missing here are not listed here):

 @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); } } 

It uses decorators like @Directive and a custom version of the TypeScript compiler that makes the interface metadata available at runtime (so ng.IQService can be translated to '$q' and ng.IQService into the constructor array). No more app.directive(...) template: everything is done in decorators :) You can see an example of application code here

+1
source

Source: https://habr.com/ru/post/989248/


All Articles