I find dependency injection for AngularJS services in TypeScript to be somewhat cumbersome. Currently, I define a factory method inside my service class, and have to repeat all dependency injection arguments three times:
class MyService {
public static Factory($rootScope, myController) { // 1st time
return new MyService($rootScope, myController); // 2nd time
}
constructor(public $rootScope, public myController) {} // 3rd time
}
myModule.factory('myService', MyService.Factory);
I would like to do the following, but that does not seem to work:
class MyService {
constructor(public $rootScope, public myController) {} // only once
}
myModule.factory('myService', MyService);
This approach works fine for controllers, but not so for services. Is there a better way?
Thanks in advance!
The D letter in SOLID is the Dependency Inversion principle. It helps to decouple modules from each other so that you can easily swap one part of the code for another. One of the techniques that helps to follow this principle is Dependency Injection.
Guide to using TypeScript in AngularJS applications. Supporting older AngularJS applications doesn't mean you can't take advantage of modern tools like TypeScript. Not every file in your application needs to be written in TypeScript at once, you just can rename all your JavaScript files to have a . ts extension.
Dependency injection (DI) is a paradigm. The way it works in Angular is through a hierarchy of injectors. A class receives its resources without having to create or know about them. Injectors receive instruction and instantiate a service depending on which one was requested.
The first step is to add the @Injectable decorator to show that the class can be injected. The next step is to make it available in the DI by providing it. A dependency can be provided in multiple places: At the Component level, using the providers field of the @Component decorator.
You should user service
not factory
:
class MyService {
constructor(public $rootScope) {} // only once
}
myModule.service('myService', MyService);
You could simply use angular's injector to create your controller instead of having a factory method.
Here is a sample in typescript
/// <reference path='d.ts/DefinitelyTyped/angularjs/angular.d.ts' />
class MyCtrl {
public phrase: string;
constructor($window) {
this.phrase = 'I was loaded by injector';
}
speak() {
alert(this.phrase);
}
}
function main() {
var injector = angular.injector(['ng']);
var ctrl = injector.instantiate(MyCtrl);
ctrl.speak();
}
And a fiddler to prove it works: http://jsfiddle.net/UPv5j/3/
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