0
export class MyDirective extends MyLib.directives.OtherDirective implements ng.IDirective {
  public require: string[] = ["^someReq"];
  public controller: string = "MyCtrl";
  public scope = {
    position: "@"
  };

  public static $inject: string[] = [
    '$http',
    '$q'
  ];
  constructor(
    private $http: ng.IHttpService,
    private $q: ng.IQService
  ) {
    console.log(this);  // undefined ??
    super($http: $http, $q: $q) // fails
  }

}

app.directive('myDirective', function (): ng.IDirective {
  return MyDirective
});

My questions is twofold here, the structure above doesn't work. (I get an error message from the super class: "Cannot set property 'restrict' of undefined when it tries the this.restrict = "A" assignment in the super class' compiled javascript).

I cannot work out why this is undefined in this case, and why it doesn't work. I suspect it may be due to my misunderstanding of how the directiveFactory works. Could someone explain why this doesn't work, and possibly demonstrate how they would achieve what I'm trying to do? (I understand that most people use functions for their directives, but trying to extend a directive from a library where the directive is a class so I am not sure how to work that in.

Edit: as a follow up- why does this work?

app.directive('myDirective', ["$http",  "$q", (
    $http: ng.IQService,
    $q: ng.IQService,
  ) => {
    return new MyDirective({$http: $http, $q: $q});
  }
]);

I Don't like it because you lose the benefits of the $inject syntax, but why does explicitly calling return new work here?

2 Answers 2

0

Angular Directives + Angular factories are not called with the new operator. Therefore you cannot use classes for them. You need to use a function. Here is what I use:

///ts:ref=globals

export interface FooDirectiveScope extends ng.IScope {
    bar: string;

    // Local design only
    vm: FooDirectiveController;
}

export class FooDirectiveController {

    static $inject = ['$element', '$scope'];
    constructor(public $element: JQuery, public $scope: FooDirectiveScope) {
        $scope.vm = this;

        // Any Jquery access goes here. Use $element

        // Setup any $watch on $scope that you need
    }
}

dustApp.directives.directive('foo', function (): ng.IDirective {
    return {
        restrict: 'E',
        scope: {
            // NOTE : see documentation in type information
            bar: '='
        },
        templateUrl: 'fooDirective.html',
        controller: FooDirectiveController
    };
});
Sign up to request clarification or add additional context in comments.

2 Comments

So you can't (or shouldn't) extend directives in typescript/angularjs? This seems like quite a limitation?
No I am saying you cannot use a class for a directive directly as it is not called with new
0

In the end, I've gone for this, taken from here

define an $injection function like so:

public static $injection(): any[] {
  return [
    '$http',
    '$q',
    ($http, $q) => new MyDirective($http, $q)
  ]
}

app.directive('rptDrawLayer', RptDrawLayer.$injection());

It's not perfect but it at least survives minification and allows me to keep using the lib's 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.