Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them, it only takes a minute:

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?

share|improve this question
    
I think you can do this.reset => { this.test = 0}; in Testscript. – accordionfolder Jun 14 at 6:47

1 Answer 1

up vote 4 down vote accepted

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|improve this answer
    
Thanks, that seems to do the trick. Any idea why the other code doesn't work? – siemprepe Apr 16 at 9:20
    
Sadly no idea :( – basarat Apr 16 at 9:35
    
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. – geekdenz Oct 21 at 5:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.