In my project, I use syntactic sugar for injection. And ES6 simplifies the use of injection factories for directives, avoiding too much code duplication. This code allows inheritance of injections, uses annotated injections and so on. Check this:
First step
Declare a base class for all angular controllers \ directives \ services - InjectableClient. The main task is to set all entered parameters as properties for 'this'. This behavior can be overridden, see Examples below.
class InjectionClient { constructor(...injected) { var injectLength = this.constructor.$inject.length; var injectedLength = injected.length; var startIndex = injectLength - injectedLength; for (var i = startIndex; i < injectLength; i++) { var injectName = this.constructor.$inject[i]; var inject = injected[i - startIndex]; this[injectName] = inject; } } static inject(...injected) { if (!this.$inject) { this.$inject = injected; } else { this.$inject = injected.concat(this.$inject); } }; }
For example, if we call SomeClassInheritedFromInjectableClient.inject ('$ scope'), in the directive or controller we will use it as' this. $ scope '
Second step
Declare the base class for the directive with the static method "factory ()", which associates the $ injected property of the directive class with the factory function. As well as the compile () method, which associates the context of the link function with the directive itself. This allows us to use our entered values inside the communication function like this.myInjectedService.
class Directive extends InjectionClient { compile() { return this.link.bind(this); } static factory() { var factoryFunc = (...injected) => { return new this(...injected); } factoryFunc.$inject = this.$inject; return factoryFunc; } }
Third step
Now we can declare as many directive classes as possible. With inheritance. And we can easily inject using distributed arrays (just remember to call the super method). Examples:
class DirectiveFirst extends Directive { } DirectiveFirst.inject('injA', 'injB', 'injC'); class DirectiveSecond extends DirectiveFirst { constructor(injD, ...injected) { super(...injected); this.otherInjectedProperty = injD; } }
Last step
Now register the directives with angular in a simple way:
angular.directive('directiveFirst', DirectiveFirst.factory()); angular.directive('directiveSecond', DirectiveSecond.factory()); angular.directive('directiveThird', DirectiveThird.factory());
Now check the code:
var factoryFirst = DirectiveFirst.factory(); var factorySec = DirectiveSecond.factory(); var factoryThird = DirectiveThird.factory(); var directive = factoryFirst('A', 'B', 'C'); console.log(directive.constructor.name + ' ' + JSON.stringify(directive)); directive = factorySec('D', 'A', 'B', 'C'); console.log(directive.constructor.name + ' ' + JSON.stringify(directive)); directive = factoryThird('D', 'A', 'B', 'C'); console.log(directive.constructor.name + ' ' + JSON.stringify(directive));
This will return:
DirectiveFirst {"injA":"A","injB":"B","injC":"C"} DirectiveSecond {"injA":"A","injB":"B","injC":"C","otherInjectedProperty":"D"} DirectiveThird {"injA":"A","injB":"B","injC":"C","otherInjectedProperty":"D"}