dependency injection angular 2 em ES5 e ES6

Aqui está um exemplo básico de TypeScript / ES.next que usa decoradores para DI e segue a syntax sugerida pelo manual do framework:

import {Component, Inject, Injectable, NgModule, OpaqueToken} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; const CONSTANT = { value: 'constant' }; const CONSTANT_TOKEN = new OpaqueToken; const CONSTANT_PROVIDER = { provide: CONSTANT_TOKEN, useValue: CONSTANT }; @Injectable() class Service { constructor(@Inject(CONSTANT_TOKEN) constant) { console.log('Service constructor', constant); } } @Component({ selector: 'app', template: '...', providers: [Service, CONSTANT_PROVIDER] }) class AppComponent { constructor(@Inject(Service) service: Service, @Inject(CONSTANT_TOKEN) constant) { console.log('AppComponent constructor', service, constant); } } @NgModule({ imports: [BrowserModule], declarations: [AppComponent], bootstrap: [AppComponent] }) class AppModule {} platformBrowserDynamic().bootstrapModule(AppModule); 

Como seria escrito no ES5?

Como seria a mesma coisa no ES6 / ES2015 não traduzido?

Como os decoradores Injectable e Inject traduzidos nesses casos?

A questão se aplica particularmente a implementações do navegador ES6 do mundo real que possuem classs, mas podem usar require ou System.import vez de importações do ES6.

Para usar o Angular 2 com o ES5, você precisa deste script:

Isso fornece uma variável global que contém todo o Angular 2. Agora você pode escrever ng.core.Component vez da anotação @Component . Os primeiros parâmetros do construtor são os injetáveis.

 var Component = ng.core Component({ selector: 'hello-cmp', template: 'Hello World!', viewProviders: [Service] .Class({ constructor: [Service, function (service) { ... }], }); 

E diga ao injector que nosso parâmetro de serviço é uma instância de Service

 Component.parameters = [[new ng.core.Inject(Service)]]; 

O Exapmle a seguir mostra o uso de angular2 com ES6 :

 import {Component} from 'angular2/core'; import {Service} from './example.service'; let componentAnnotation = new Component({ selector: 'world-time', inputs: ['timeZones'], providers: [Service], template: ` ... ` }); export class ComponentExample { constructor(service) { this._service = service; } ... } WorldTimeComponent.annotations = [componentAnnotation]; WorldTimeComponent.parameters = [[Service]]; 

Neste plunkr você pode encontrar um exemplo de ES6 funcional.

Mas você pode usar decoradores usando o Babel . Ativando os optional[]=es7.decorators (no webpack) ou definindo sua configuração para o stage:1 .

Decorador Injectable é específico para o tipo TypeScript de Angular 2. Ele permite que um construtor de class seja implicitamente anotado para DI através de annotations do tipo TypeScript. É redundante em TS e desnecessário em JS para dependencies injetadas que são anotadas com Inject .

Angular 2 injetáveis ​​(classs e funções construtoras) devem ser anotados com annotations e parameters propriedades estáticas sob o capô.

annotations é uma matriz que contém new decoradores ed para class injetável:

 function SomeComponent(...) {} SomeComponent.annotations = [new Componenent(...)]; 

parameters é uma matriz que contém decoradores para parâmetros de construtor, cada elemento é uma matriz que contém uma lista de new decoradores ed para a respectiva propriedade de construtor (semelhante à anotação explícita da propriedade $inject em Angular 1.x):

 function Service(someService, anotherService) {} Service.parameters = [ [new Inject(SomeService)], [new Inject(AnotherService), new Optional, new SkipSelf] ]; 

Todos os decoradores de classs são estendidos do TypeDecorator , o que significa que eles podem ser chamados como funções. Nesse caso, é usada a chamada syntax DSL, que permite encadear um decorador com a function auxiliar de Class :

 var SomeComponent = Componenent(...).Class(...); 

Class também está disponível separadamente, ela constrói uma nova class a partir de determinado object de definição e permite anotar o método constructor com array (similarmente à anotação explícita da matriz inline no Angular 1.x):

 var SomeService = Class({ constructor: [[new Inject(SomeService)], function (someService) {}] }); 

Class auxiliar de Class foi descontinuado nas versões mais recentes do framework. É suposto ser substituído por funções brutas ou ajudantes de class de terceiros no ES5. Decoradores suportam encadeamento direto com funções de class, Componenent(...)(ComponentClass) .

Angular 2/4 ES6 com System.import

Um exemplo :

 Promise.all([ System.import('@angular/core'), System.import('@angular/platform-browser'), System.import('@angular/platform-browser-dynamic') ]) .then(([ {Component, Inject, Injectable, Optional, NgModule, OpaqueToken}, {BrowserModule}, {platformBrowserDynamic} ]) => { const CONSTANT = { value: 'constant' }; const CONSTANT_TOKEN = new OpaqueToken; const CONSTANT_PROVIDER = { provide: CONSTANT_TOKEN, useValue: CONSTANT }; class Service { constructor(constant) {} } Service.parameters = [[new Inject(CONSTANT_TOKEN)]]; class AppComponent { constructor(service, constant) {} } AppComponent.annotations = [new Component({ selector: 'app', template: '...', providers: [Service, CONSTANT_PROVIDER] })]; AppComponent.parameters = [[new Inject(Service)], [new Inject(CONSTANT_TOKEN)]]; class AppModule {} AppModule.annotations = [new NgModule({ imports: [BrowserModule], declarations: [AppComponent], bootstrap: [AppComponent] })]; platformBrowserDynamic().bootstrapModule(AppModule); }) .catch((err) => console.error(err)); 

Angular 2/4 ES5 com módulos UMD e ng global

Um exemplo :

 var Class = ng.core.Class; var Component = ng.core.Component; var Inject = ng.core.Inject; var Injectable = ng.core.Injectable; var NgModule = ng.core.NgModule; var OpaqueToken = ng.core.OpaqueToken; var BrowserModule = ng.platformBrowser.BrowserModule; var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic; var CONSTANT = { value: 'constant' }; var CONSTANT_TOKEN = new OpaqueToken; var CONSTANT_PROVIDER = { provide: CONSTANT_TOKEN, useValue: CONSTANT }; // Class helper function that uses A1-flavoured inline array DI annotations // and creates an annotated constructor var Service = Class({ constructor: [[new Inject(CONSTANT_TOKEN)], function (constant) { console.log('Service constructor', constant); }] }); // can also be // function Service(constant) {}; // Service.parameters = [[new Inject(...)], ...]; // when not being `new`ed, Component is a chainable factory that has Class helper method var AppComponent = Component({ selector: 'app', template: '...', providers: [Service, CONSTANT_PROVIDER] }) .Class({ constructor: [ [new Inject(Service)], [new Inject(CONSTANT_TOKEN)], function (service, constant) { console.log('AppComponent constructor', service, constant); } ] }); // can also be // function AppComponent(...) {}; // AppComponent.annotations = [new Component(...)]; // AppComponent.parameters = [[new Inject(...)], ...]; var AppModule = NgModule({ imports: [BrowserModule], declarations: [AppComponent], bootstrap: [AppComponent] }) .Class({ constructor: function () {} }); // can also be // function AppModule() {}; // AppModule.annotations = [new NgModule(...)]; platformBrowserDynamic().bootstrapModule(AppModule);