ES5和ES6中的角2依赖注入 [英] Angular 2 dependency injection in ES5 and ES6
问题描述
这是一个基本的TypeScript / ES.next示例,它使用装饰器DI和遵循框架手册建议的语法:
import {Component,Inject,Injectable,NgModule,OpaqueToken} from'@ angular /核心';来自'@ angular / platform-browser'的
import {BrowserModule};
import {platformBrowserDynamic} from'@ angular / platform-browser-dynamic';
const CONSTANT = {value:'constant'};
const CONSTANT_TOKEN = new OpaqueToken;
const CONSTANT_PROVIDER = {提供: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构造函数,服务,常量);
}
@NgModule({
imports:[BrowserModule],
声明:[AppComponent],
bootstrap:[AppComponent ]
})
class AppModule {}
platformBrowserDynamic()。bootstrapModule(AppModule);
如何在ES5中写入?
ES6 / ES2015?如何可注入
和注入
在这些情况下翻译的装饰器?
该问题特别适用于真实世界的ES6浏览器具有类但可以使用的实现需要
或 System.import
而不是ES6导入。
可注入
decorator是特定于Angular 2的TypeScript风格。它使类构造函数能够隐式通过TypeScript类型注释注释为DI。它在TS中是冗余的,并且在JS中不需要注入注释的依赖关系,注释为 Inject
。
Angular 2 injectables类和构造函数)应该使用注释
和参数
注释静态属性。
注释
是一个数组,包含 new
ed可注册类的装饰器:
function SomeComponent(...){}
SomeComponent.annotations = [new Componenent(...)] ;
参数
是一个数组,包含构造函数参数,每个元素都是一个数组,它包含一个列表,用于各个构造函数属性的 new
ed装饰符(类似于 $ inject
Angular 1.x中的属性显式注释):
function Service(someService,anotherService){}
服务。 parameters = [
[new Inject(SomeService)],
[new Inject(AnotherService),new可选,新的SkipSelf]
];
所有类装饰器都从 TypeDecorator
,这意味着它们可以被称为函数。在这种情况下,使用所谓的DSL语法,可以使用 类
帮助函数:
var SomeComponent = Componenent(...)。Class(...);
Class
也可单独使用,来自给定定义对象的新课程,并允许使用数组注释构造函数
方法(类似于Angular 1.x中的内联数组显式注释):
var SomeService = Class({
constructor:[[new Inject(SomeService)],function(someService){}]
});
这是如何 ES6 with System.import
可能如下所示:
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 = {提供:CONSTANT_TOKEN,useValue:CONSTANT};
类服务{
构造函数(常量){}
}
Service.parameters = [[new Inject(CONSTANT_TOKEN)]];
class AppComponent {
构造函数(服务,常量){}
}
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],
声明:[AppComponent],
bootstrap :[AppComponent]
})];
platformBrowserDynamic()。bootstrapModule(AppModule);
})
.catch((err)=> console.error(err));
这是如何 ES5与UMD模块和 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};
//使用A1风格的内联数组DI注释
//并创建一个注释构造函数的类助手函数
var Service = Class({
constructor:[ [new Inject(CONSTANT_TOKEN)],function(constant){
console.log('Service constructor',constant);
}]
});
//也可以是
// function Service(constant){};
// Service.parameters = [[new Inject(...)],...];
//当不是`new`ed时,组件是一个具有类助手方法的可链接工厂
var AppComponent = Component({
selector:'app',
template:'...',
providers:[Service,CONSTANT_PROVIDER]
})
.Class({
constructor:[
[new Inject服务)],
[new Inject(CONSTANT_TOKEN)],
函数(服务,常量){
console.log('AppComponent constructor',service,constant);
}
]
});
//也可以是
//函数AppComponent(...){};
// AppComponent.annotations = [new Component(...)];
// AppComponent.parameters = [[new Inject(...)],...];
var AppModule = NgModule({
imports:[BrowserModule],
声明:[AppComponent],
bootstrap:[AppComponent]
})
.Class({constructor:function(){}});
//也可以是
//函数AppModule(){};
// AppModule.annotations = [new NgModule(...)];
platformBrowserDynamic()。bootstrapModule(AppModule);
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.
Injectable
decorator is specific to TypeScript flavour of Angular 2. It enables a class constructor to be implicitly annotated for DI through TypeScript type annotations. It is redundant in TS and unneeded in JS for injected dependencies that are annotated with Inject
.
Angular 2 injectables (classes and constructor functions) are supposed to be annotated with annotations
and parameters
static properties under the hood.
annotations
is an array that contains new
ed decorators for injectable class:
function SomeComponent(...) {}
SomeComponent.annotations = [new Componenent(...)];
parameters
is an array that contains decorators for constructor parameters, each element is an array that contains a list of new
ed decorators for respective constructor property (similarly to $inject
property explicit annotation in Angular 1.x):
function Service(someService, anotherService) {}
Service.parameters = [
[new Inject(SomeService)],
[new Inject(AnotherService), new Optional, new SkipSelf]
];
All class decorators are extended from TypeDecorator
, meaning that they can be called as functions. In this case so-called DSL syntax is used that allows to chain a decorator with Class
helper function:
var SomeComponent = Componenent(...).Class(...);
Class
is also available separately, it constructs a new class from given definition object and allows to annotate constructor
method with array (similarly to inline array explicit annotation in Angular 1.x):
var SomeService = Class({
constructor: [[new Inject(SomeService)], function (someService) {}]
});
This is how ES6 with System.import
may look like:
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));
This is how ES5 with UMD modules and ng
global may look like:
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);
这篇关于ES5和ES6中的角2依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!