这是一个基本的TypeScript / ES.next示例,该示例使用装饰符进行DI并遵循框架手册建议的语法:
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);
如何用ES5编写?
如何将同样的事情在做 untranspiled ES6 / ES2015?
在这种情况下Injectable,Inject装饰器如何翻译?
Injectable
Inject
该问题尤其适用于具有类但可以使用require或System.import代替ES6导入的具有类的真实ES6浏览器实现。
require
System.import
Injectable装饰器特定于Angular2的TypeScript风格。它使类构造函数可以通过TypeScript类型注释为DI隐式注释。在TS中是多余的,在JS中对于用注释的注入依赖项则不需要Inject。
Angular 2注入对象(类和构造函数)应该在引擎盖下带有annotations,parameters静态属性进行注释。
annotations
parameters
annotations是一个数组,其中包含new用于可注入类的ed装饰器:
new
function SomeComponent(...) {} SomeComponent.annotations = [new Componenent(...)];
parameters是一个包含用于构造函数参数的修饰符的数组,每个元素是一个包含new用于相应构造函数属性的ed装饰符列表的数组(类似于$injectAngular1.x中的属性显式注释):
$inject
function Service(someService, anotherService) {} Service.parameters = [ [new Inject(SomeService)], [new Inject(AnotherService), new Optional, new SkipSelf] ];
所有类装饰器都从扩展TypeDecorator,意味着它们可以被称为函数。在这种情况下,使用所谓的DSL语法,该语法允许将装饰器与Class辅助函数链接在一起:
TypeDecorator
Class
var SomeComponent = Componenent(...).Class(...);
Class也可以单独使用,它从给定的定义对象构造一个新类,并允许constructor使用数组对方法进行注释(类似于Angular 1.x中的内联数组显式注释):
constructor
var SomeService = Class({ constructor: [[new Inject(SomeService)], function (someService) {}] });
Class在最新的框架版本中不推荐使用helper。应该在ES5中将其替换为原始函数或第三方类帮助器。装饰器支持与类函数直接链接Componenent(...)(ComponentClass)。
Componenent(...)(ComponentClass)
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));
ng
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);