5

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?

1
  • I think you can do this.reset => { this.test = 0}; in Testscript. Commented Jun 14, 2015 at 6:47

1 Answer 1

18

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).

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

2 Comments

Thanks, that seems to do the trick. Any idea why the other code doesn't work?
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.

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.