Lets say I have a simple angular directive that looks like this:
app.directive(\'setFocus\', [\'$timeout\', function($timeout) {
return {
restrict: \'AC\
To avoid all the factory boilerplate (and the constructor array at all), I recently wrote a small library (currently as a test project), that make the definition of directives very simple (controller and template omitted here):
@Directive('userRank')
export class UserRankDirective implements ng.IDirective {
controller = UserRankDirectiveController;
restrict = 'A';
template = template;
//controllerAs: 'ctrl', set as default
replace = true;
scope = {
user: '=userRank'
}
constructor($q: ng.IQService) {
console.log('Q service in UserRankDirective:', $q);
}
}
It uses decorators like @Directive
and a customized version of the TypeScript compiler that make interfaces metadata available at runtime (so ng.IQService
can be translated to '$q'
and injected in the constructor array).
No more app.directive(...)
boilerplate: everything is done in decorators :)
You can give a look at the sample application code here
Try this way:
class SetFocus implements ng.IDirective {
//Directive settings
restrict :string = 'EA';
scope : any= {};
//Take timeout argument in the constructor
constructor(private $timeout: ng.ITimeoutService) {
}
link: ng.IDirectiveLinkFn = ($scope: ng.IScope, $element: ng.IAugmentedJQuery, $attrs: ng.IAttributes) => {
//refer to the timeout
this.$timeout(function() {
$element[0].focus();
}, 0);
}
//Expose a static func so that it can be used to register directive.
static factory(): ng.IDirectiveFactory {
//Create factory function which when invoked with dependencies by
//angular will return newed up instance passing the timeout argument
var directive: ng.IDirectiveFactory =
($timeout:ng.ITimeoutService) => new SetFocus($timeout);
//directive's injection list
directive.$inject = ["$timeout"];
return directive;
}
}
directives.directive('setFocus', SetFocus.factory());
It could be a problem with the way you have it right now. Because directive factory is not newed up so its constructor will execute with this
as global object. This way you don't end up having a huge constructor as well and can write it in proper class ey manner.
If you have many dependencies injected instead of repeating the arguments in the factory you could as well do:
var directive: ng.IDirectiveFactory =
(...args) => new (SetFocus.bind.apply(SetFocus, [null].concat(args)));