1

I trie to implement a new directive in my app. Directive's code :

module Myapp.NV.Directives {

export interface placeHolderScope extends ng.IScope {
    txt: string;
}

/**
* PlaceHolder
*
*  @class
*  @classdesc This directive is use to simulate placeholder HTML5 attributes
*/
export class PlaceHolder implements IDirective {
    static $inject = ['$log','$timeout'];
    constructor($log: ng.ILogService, $timeout: ng.ITimeoutService) {
        var txt;
        var directive: any = {
            restrict: "A",
            scope: { txt: "@ngPlaceholder" },
            link: function (scope: placeHolderScope, elem: ng.IAugmentedJQuery, attrs: ng.IAttributes, $log: ng.ILogService, $timeout: ng.ITimeoutService) {
                console.log($log);
                console.log($timeout);
            }
        }
        return directive;
    }
}
}

 Myapp.NV.registerDirective('PlaceHolder', ['$log', '$timeout']);

My probleme is log and timeout are always undefined...

static $inject = ['$log','$timeout'];

Won't work...

The code for registerDirective function :

export function registerDirective(className: string, services = []) {
    var directive = className[0].toLowerCase() + className.slice(1);
    services.push(() => new Myapp.NV.Directives[className]());
    angular.module('Myapp.NV.Directives').directive(directive, services);
}

Thanks for help me :)

2 Answers 2

5

As boindill points out in the original answer, dependencies are injected through the TypeScript constructor, not through the link function.

This is my solution, myDirective depends on myService:

export class MyDirective implements ng.IDirective {
    static $inject = ["myService"];

    constructor(private myService: IMyService) {
    }

    restrict = "A";

    scope = {};

    link = (scope: IMyScope, element: ng.IAugmentedJQuery, attributes: ng.IAttributes) => {
        // directive implementation
        // Access myService through 'this.myService'.
    };
}

Register the directive in Angular the following way. Here ng.IDirectiveFactory is implemented as an anonymous function:

angular.module("app", []).directive("myDirective", (myService: IMyService) => {
    return new MyDirective(myService);
});

Here the Angular dependency injection works because it recognizes the constructor parameter names (myService).

To make sure dependency injection still recognizes the dependencies when the generated JavaScript is minified the static $inject property provides their names in a string array. Just as with plain JavaScript, make sure the constructor parameters and the $inject array members are in the same order.

Sign up to request clarification or add additional context in comments.

1 Comment

Does this solution work with minification? The dependency on the parameter name suggests it wouldn't.
0

You cannot inject dependencies in the link function of a directive. The link function has a fixed signature function link(scope, element, attrs) { ... } this is taken from the official angularjs documentation.

What you is to define a controller for your directive and inject the dependencies into the controller. Afterwards just use this controller function.

1 Comment

This is not good advice, using a controller in order to have access to external services. You can have access to injected services in a link function by injecting them to the constructor function for the directive itself: angular.directive('directiveName', function('inject_services_here') {}); This way you can use the link function for manipulating the DOM and the controller for View-Model logic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.