[英]Angular 2 dependency injection in ES5 and ES6
Here is a basic TypeScript/ES.next example that uses decorators for DI and follows the syntax suggested by the framework manual: 这是一个基本的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);
How would it be written in in ES5? 如何在ES5中编写?
How would the same thing be done in untranspiled ES6/ES2015? 如何将同样的事情在untranspiled ES6 / ES2015做什么?
How are Injectable
and Inject
decorators translated in these cases? 在这些情况下,如何翻译可Injectable
和Inject
装饰器?
The question particularly applies to real-world ES6 browser implementations that have classes but may use require
or System.import
instead of ES6 imports. 这个问题特别适用于具有类但可能使用require
或System.import
而不是ES6导入的实际ES6浏览器实现。
To use Angular 2 with ES5 you need this script: 要将Angular 2与ES5一起使用,您需要以下脚本:
<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. 这提供了一个包含所有Angular 2的全局变量。现在您可以编写ng.core.Component
而不是@Component
注释。 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
告诉注入器我们的服务参数是Service
一个实例
Component.parameters = [[new ng.core.Inject(Service)]];
The following Exapmle shows the usage of angular2 with ES6 : 以下Exapmle显示了使用ES6的angular2:
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. 在这个plunkr中你可以找到一个有效的ES6例子。
But you can use decorators by using Babel . 但是你可以使用Babel来使用装饰器。 Enabling the optional[]=es7.decorators
(in webpack) or by setting your configuration to stage:1
. 启用optional[]=es7.decorators
(在webpack中)或将配置设置为stage:1
。
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. Injectable
装饰器特定于Angular 2的TypeScript风格。它允许通过TypeScript类型注释对DI隐式注释类构造函数。 It is redundant in TS and unneeded in JS for injected dependencies that are annotated with Inject
. 它在TS中是冗余的,在JS中不需要注入使用Inject
注释的依赖项。
Angular 2 injectables (classes and constructor functions) are supposed to be annotated with annotations
and parameters
static properties under the hood. Angular 2 injectables(类和构造函数)应该在引擎盖下annotations
和parameters
静态属性。
annotations
is an array that contains new
ed decorators for injectable class: annotations
是一个包含可注入类的new
ed装饰器的数组:
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): parameters
是一个包含构造函数参数的装饰器的数组,每个元素都是一个数组,其中包含各个构造函数属性的new
ed装饰器列表(类似于Angular 1.x中的$inject
属性显式注释):
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. 所有类装饰器都从TypeDecorator
扩展,这意味着它们可以作为函数调用。 In this case so-called DSL syntax is used that allows to chain a decorator with Class
helper function : 在这种情况下,使用所谓的DSL语法,允许使用Class
辅助函数链接装饰器:
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): Class
也可单独使用,它从给定的定义对象构造一个新类,并允许使用数组注释constructor
方法(类似于Angular 1.x中的内联数组显式注释):
var SomeService = Class({
constructor: [[new Inject(SomeService)], function (someService) {}]
});
Class
helper was deprecated in latest framework versions. 在最新的框架版本中不推荐使用Class
助手。 It is supposed to be replaced with raw functions or third-party class helpers in ES5. 它应该被ES5中的原始函数或第三方类助手替换。 Decorators support direct chaining with class functions, Componenent(...)(ComponentClass)
. 装饰器支持直接链接类函数, Componenent(...)(ComponentClass)
。
System.import
带有System.import
Angular 2/4 ES6 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
global 具有UMD模块和ng
全局的Angular 2/4 ES5 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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.