Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 dependency injection in ES5 and ES6

Tags:

Here is a basic TypeScript/ES.next example that uses decorators for DI and follows the syntax suggested by the framework manual:

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); 

How would it be written in in ES5?

How would the same thing be done in untranspiled ES6/ES2015?

How are Injectable and Inject decorators translated in these cases?

The question particularly applies to real-world ES6 browser implementations that have classes but may use require or System.import instead of ES6 imports.

like image 300
Estus Flask Avatar asked Aug 09 '16 19:08

Estus Flask


1 Answers

To use Angular 2 with ES5 you need this script:

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.3/angular2-all.umd.js"></script>

This provides an global variable that contains all of Angular 2. Now you can write ng.core.Component instead of the @Component annotation. The first parameters of the Constructor are the injectables.

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

And tell the injector that our service parameter is a instance of Service

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


The following Exapmle shows the usage of angular2 with 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]]; 

In this plunkr you can find a working ES6 example.

But you can use decorators by using Babel. Enabling the optional[]=es7.decorators (in webpack) or by setting your configuration to stage:1.

like image 156
muetzerich Avatar answered Sep 17 '22 01:09

muetzerich