5

I am having issues injecting $compile in the following directive.

export class Element {
    public link(scope:dirScopeInterface, element:any, attrs:ng.IAttributes, formCtrl:ng.IFormController) {
        var attr = this.arrayJoiner(scope.standard, scope.attrs || {}, scope.ignore || {});
        element.html(this.compiler(attr));
        $compile(element.contents())(scope);
    }
}

At the moment it is throwing an $compile is undefined error. I have tried using

static $inject = ['$compile'];

But it disappears from the transpiled script for some reason.

Here is the full code used.

3 Answers 3

9

Include the static $inject and a constructor:

export class Element {

    // $compile can then be used as this.$compile
    constructor(private $compile: ng.ICompileService){};

    public link(scope:dirScopeInterface, element:any, attrs:ng.IAttributes, formCtrl:ng.IFormController) {
        var attr = this.arrayJoiner(scope.standard, scope.attrs || {}, scope.ignore || {});
        element.html(this.compiler(attr));
        this.$compile(element.contents())(scope);
    }
}

EDIT

To register this directive with angular, this is what I always do (there are multiple solutions):

export class Element implements angular.IDirective {

    public static ID = "element";

    // This can then be removed:
    // static $inject = ["$compile"];

    // ..

    /**
     * The factory function that creates the directive
     */
    static factory(): angular.IDirectiveFactory {
        const directive = ($compile) => new Element($compile);
        directive.$inject = ["$compile"];
        return directive;
    }
}

and to register:

angular.module("myModule" [])
    .directive(Element.ID, Element.factory());
Sign up to request clarification or add additional context in comments.

6 Comments

How would I register this directive with angular then as the constructor requires a parameter? Also I have implemented it the way you specified but am getting an $compile is not a function error.
Angular uses dependency injection, so the constructor will resolve itself. You have to use the pointer to the controller to get to the private $compile variable: this.$compile
It looks like tho following: static $inject = ['$compile']; constructor(private $compile:ng.ICompileService){} public link = (scope:dirScopeInterface, element:any, attrs:ng.IAttributes, formCtrl:ng.IFormController) => { scope.tempForm = formCtrl; var attr = this.arrayJoiner(scope.standard, scope.attrs || {}, scope.ignore || {}); element.html(this.compiler(attr)); this.$compile(element.contents())(scope); } Angular throws an $compile not a function error.
I've added how I always register such typescript directives
@devqon: Where do I find Directive, to use in new Directive?
|
0

So I found a way to get it to work but it is not as elegant as I would have liked.

angular.module('formDirectives', [], function($compileProvider){
    $compileProvider.directive('catElement', ($compile) => {
        return new Element($compile);
    });
})

Comments

0

my implementation for jQuery Wizard Steps with AngularJS + Typescripts

It should work well for other $compile function too.

AppDirective.ts

 export class stepwizard implements ng.IDirective {
    constructor() {
        console.log("construtor step wizard directive");
    }

    link($scope: ng.IScope, $element: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController, ctrl: any) {
        console.log("start step wizard link function");
        $element.wrapInner('<div class="steps-wrapper">');
        const steps = $element.children(".steps-wrapper").steps({
            headerTag: "h3",
            bodyTag: "section",
            transitionEffect: "slideLeft",
            autoFocus: true
        });
        const compiled = ctrl.$compile(steps);
    }

    public static Factory() {
        var directive = () => {
            return new stepwizard();
        };

        directive.$inject = ['$compile'];
        console.log("initial step wizard");

        return directive;
    }
}

AppController.ts

    export class pageController{
    // your declaraction
    static $inject: Array<string> = [
      $compile',
    ];
    constructor(
      $compile: ng.ICompileService,
    ) {
    // your constructor declaraction
    }

HTML

// sample take from official website
             <div stepwizard>
                <h3>Keyboard</h3>
                <section>
                    <p>Try the keyboard navigation by clicking arrow left or right!</p>
                </section>
                <h3>Effects</h3>
                <section>
                    <p>Wonderful transition effects.</p>
                </section>
                <h3>Pager</h3>
                <section>
                    <p>The next and previous buttons help you to navigate through your content.</p>
                </section>
            </div>

directives.stepwizard = <namespace>.directives.stepwizard.Factory();
app.directive(directives);

Comments

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.