babel-plugin-angularjs-annotate
babel-plugin-angularjs-annotate copied to clipboard
Option for a decorator
Making this possible:
@inject('$q')
class Controller {
constructor() {
console.log(this.$q);
}
}
I have been using it for a while in our project
// ./inject-decorator.ts
import * as angular from 'angular';
let _$injector: angular.auto.IInjectorService;
export function registerInjectDecoratorModule() {
return angular.module('td.injector', []).run(function registerInjectDecorator($injector) {
_$injector = $injector;
}).name;
}
/**
* Usage property dependency injector decorator
*
* Usage:
*
* import {inject} from '@libs/inject-decorator';
*
* class Foo {
*
* @inject() //property name the same as service name
* private someService: SomeService
*
* @inject('barService') //explicit pass name of service to inject
* private bar: BarService
*
* }
*/
export function inject(name?: string) {
return function injectDecorator(target: any, key: string) {
Object.defineProperty(target, key, {
get: () => {
const value = _$injector.get(name || key);
Object.defineProperty(target, key, {
value,
writable: false,
enumerable: false,
configurable: false,
});
return value;
},
enumerable: false,
configurable: true,
});
};
}
Add injector decorator module to your root module in the top of queue before any other:
// app.ts - root module
const appModule = angular.module('app', [
registerInjectDecoratorModule(),
// your other modules ...
])
Then use it this way:
import { inject } from '../libs/inject-decorator';
export class AuthPopup {
@inject() private $q: ng.IQService;
@inject() private commonAnalytics: CommonAnalytics;
@inject() private $rootScope: ng.IRootScopeService;
}
Notice
Injects with this decorator are lazy. Services will be injected and instantiated only when you access a property. This might break some of your flows.