ES5和ES6中的Angular 2依赖注入
Angular 2 dependency injection in ES5 and ES6
这是一个基本的TypeScript/ES。下一个使用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中怎么写呢?
如何在未编译的 ES6/ES2015中完成同样的事情?
在这些情况下,Injectable
和Inject
装饰符是如何翻译的?
这个问题特别适用于真实的ES6浏览器实现,它有类,但可能使用require
或System.import
而不是ES6导入。
要在ES5中使用Angular 2,你需要这个脚本:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.3/angular2-all.umd.js"></script>
它提供了一个全局变量,它包含了Angular 2的所有内容。现在您可以编写ng.core.Component
而不是@Component
注释。构造函数的第一个参数是可注入对象。
var Component = ng.core
Component({
selector: 'hello-cmp',
template: 'Hello World!',
viewProviders: [Service]
.Class({
constructor: [Service, function (service) {
...
}],
});
并告诉注入器我们的service参数是Service
的一个实例
Component.parameters = [[new ng.core.Inject(Service)]];
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]];
下面是一个ES6的例子。
但是你可以通过使用Babel来使用装饰器。启用optional[]=es7.decorators
(在webpack中)或通过将配置设置为stage:1
。
Injectable
装饰器是Angular 2中TypeScript风格特有的。它允许通过TypeScript类型注释为DI隐式地注释类构造函数。它在TS中是多余的,在JS中是不必要的,因为注入的依赖是用Inject
注释的。
Angular 2的注入(类和构造函数)应该在底层使用annotations
和parameters
静态属性进行注释。
annotations
是一个数组,包含可注入类的new
装饰符:
function SomeComponent(...) {}
SomeComponent.annotations = [new Componenent(...)];
parameters
是一个数组,它包含了构造函数参数的装饰器,每个元素都是一个数组,其中包含了相应构造函数属性的new
装饰器列表(类似于Angular 1.x中$inject
属性的显式注释):
function Service(someService, anotherService) {}
Service.parameters = [
[new Inject(SomeService)],
[new Inject(AnotherService), new Optional, new SkipSelf]
];
所有的类装饰器都是从TypeDecorator
扩展而来的,这意味着它们可以作为函数调用。在这种情况下,使用了所谓的DSL语法,它允许将decorator与Class
helper函数链接:
var SomeComponent = Componenent(...).Class(...);
Class
也可以单独使用,它从给定的定义对象构造一个新类,并允许用数组注释constructor
方法(类似于Angular 1.x中的内联数组显式注释):
var SomeService = Class({
constructor: [[new Inject(SomeService)], function (someService) {}]
});
Class
helper在最新框架版本中已弃用。在ES5中,它应该被原始函数或第三方类帮助器取代。Componenent(...)(ComponentClass)
.
Angular 2/4 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 = { 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与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 };
// 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);
- AngularJS依赖注入定时问题
- JavaScript模块化和依赖注入之间的区别
- 编写Karma+Mocha测试,同时使用依赖注入和“完成”
- Angular2文档-层次依赖注入程序(恢复服务)
- 使用依赖注入在 JavaScript 中返回函数
- 如何从指令的控制器调用依赖注入服务的嵌套方法
- AngularJS'依赖注入和RequireJS本质上是相同的
- 为Backbone.js应用程序设计依赖注入系统的范围界定问题
- 当使用Angular1+ES6时,控制器函数中未定义依赖注入,控制器是一个类
- 角度依赖注入,使用服务在模块之间传递值
- 如何使用JS(浏览器端)中的“require”和依赖注入,服务位置
- Angular ui-router 解析中的动态依赖注入
- Angularjs |依赖注入优于需要模块的优势
- AngularJS 依赖注入在哪里指定
- 如何在 Nodejs 中进行有效的依赖注入
- 无法解决条带角依赖注入
- Undefined不是函数和依赖注入
- Angular 指令是否需要将依赖注入到控制器中
- AngularJS中的依赖注入仅适用于Angular“对象”吗?
- 角度依赖注入,如果将控制器、服务等分离到单独的模块中