Typescript angular directive controller function

10,421

This is the directive design that we've been using :

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
    }
}

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

    // Local design only
    vm: FooDirectiveController;
}

dustApp.directives.directive('foo', function (): ng.IDirective {
    return {
        restrict: 'E',
        scope: {
            // NOTE : see documentation in type information
            bar: '='
        },
        templateUrl: 'fooDirective.html',
        controller: FooDirectiveController
    };
});

This way you controller is strongly typed and the directive definition object is dumb (and possibly angular 2 compatible).

Share:
10,421
siemprepe
Author by

siemprepe

Updated on June 07, 2022

Comments

  • siemprepe
    siemprepe about 2 years

    I have an issue writing angular directives in typescript. I want to write my directives using typescript classes. Everything works fine except the controller function.

    class myDirective implements ng.IDirective{
    
    public priority :number = 999;
    public require :String[] = ["ngModel","myDirective"];
    
    public controller(){
        var test = 1;
        return {
          reset : function(){
             test = 0;
      }
        }
    }
    
    public link($scope: ng.IScope, elm: JQuery, attr: ng.IAttributes, ctrlArray: any){
        var controller;
        controller = ctrlArray[1];
        controller.reset();
    }
    
    static factory(): ng.IDirectiveFactory{
        var directive = () => new myDirective();
        return directive;
    }
    }
    export = myDirective;
    

    But when running this in angular I get a "undefined is not a function" when controller.reset() is called inside the link function. When I inspect controller i just get prototype Object, there is no reset function defined.

    When I write my directive like this, it works.

    function myDirective(): ng.IDirective{
    return {
        priority: 999,
        require: ["ngModel","myDirective"],
        controller: function(){
            var test = 1;
            this.reset = function(){
                test = 0;
            }
        },
        link: function($scope: ng.IScope, elm: JQuery, attr: ng.IAttributes, ctrlArray: any){
            var controller;
            controller = ctrlArray[1];
            controller.reset();
        }
    }
    }
    export = myDirective;
    

    The difference is in the way the controller function is written. In the typescript class I use.

    return {
          reset : function(){
             test = 0;
      }
        }
    

    in the function way I use

    this.reset = function(){
                test = 0;
            }
    

    Unfortunately, typescript doesn't let me use the second way inside a typescript class. IS there anything I am missing, or am I approaching this entirely from the wrong angle?

  • siemprepe
    siemprepe about 9 years
    Thanks, that seems to do the trick. Any idea why the other code doesn't work?
  • geekdenz
    geekdenz over 8 years
    github.com/angular/angular.js/blob/v1.4.7/src/ng/… This line is the reason. The function is called with javascript fn.apply(null, arguments) So, this becomes null in this context.