Recently I started refactoring one of the Angular projects I am working on with TypeScript. Using TypeScript classes to define controllers is very convenient and works well with minified JavaScript files thanks to static $inject Array<string>
property. And you get pretty clean code without splitting Angular dependencies from the class definition:
module app { 'use strict'; export class AppCtrl { static $inject: Array < string > = ['$scope']; constructor(private $scope) { ... } } angular.module('myApp', []) .controller('AppCtrl', AppCtrl); }
Right now I am searching for solution to handle similar case for the directive definition. I found a good practice to define the directives as function:
module directives { export function myDirective(toaster): ng.IDirective { return { restrict: 'A', require: ['ngModel'], templateUrl: 'myDirective.html', replace: true, link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, ctrls) => //use of $location service ... } }; } angular.module('directives', []) .directive('myDirective', ['toaster', myDirective]); }
In this case I am forced to define Angular dependencies in the directive definition, which can be very error-prone if the definition and TypeScript class are in different files. What is the best way to define directive with typescript and the $inject
mechanism, I was searching for a good way to implement TypeScript IDirectiveFactory
interface but I was not satisfied by the solutions I found.
AngularJS directives are extended HTML attributes with the prefix ng- . The ng-app directive initializes an AngularJS application. The ng-init directive initializes application data. The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.
TypeScript is a primary language for Angular application development. It is a superset of JavaScript with design-time support for type safety and tooling. Browsers can't execute TypeScript directly. Typescript must be "transpiled" into JavaScript using the tsc compiler, which requires some configuration.
A controller is usually used to contain and maintain the logic for your view, which gets bound to your view via $scope. A directive is something that you might use repeatedly and is called in your view directly through the directive name which you can pass in as an attribute.
Using classes and inherit from ng.IDirective is the way to go with TypeScript:
class MyDirective implements ng.IDirective { restrict = 'A'; require = 'ngModel'; templateUrl = 'myDirective.html'; replace = true; constructor(private $location: ng.ILocationService, private toaster: ToasterService) { } link = (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, ctrl: any) => { console.log(this.$location); console.log(this.toaster); } static factory(): ng.IDirectiveFactory { const directive = ($location: ng.ILocationService, toaster: ToasterService) => new MyDirective($location, toaster); directive.$inject = ['$location', 'toaster']; return directive; } } app.directive('mydirective', MyDirective.factory());
Related answer: https://stackoverflow.com/a/29223360/990356
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With