[英]Angular 2 dependency injection in ES5 and ES6
這是一個基本的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
裝飾器?
這個問題特別適用於具有類但可能使用require
或System.import
而不是ES6導入的實際ES6瀏覽器實現。
要將Angular 2與ES5一起使用,您需要以下腳本:
<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
一個實例
Component.parameters = [[new ng.core.Inject(Service)]];
以下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]];
在這個plunkr中你可以找到一個有效的ES6例子。
但是你可以使用Babel來使用裝飾器。 啟用optional[]=es7.decorators
(在webpack中)或將配置設置為stage:1
。
Injectable
裝飾器特定於Angular 2的TypeScript風格。它允許通過TypeScript類型注釋對DI隱式注釋類構造函數。 它在TS中是冗余的,在JS中不需要注入使用Inject
注釋的依賴項。
Angular 2 injectables(類和構造函數)應該在引擎蓋下annotations
和parameters
靜態屬性。
annotations
是一個包含可注入類的new
ed裝飾器的數組:
function SomeComponent(...) {}
SomeComponent.annotations = [new Componenent(...)];
parameters
是一個包含構造函數參數的裝飾器的數組,每個元素都是一個數組,其中包含各個構造函數屬性的new
ed裝飾器列表(類似於Angular 1.x中的$inject
屬性顯式注釋):
function Service(someService, anotherService) {}
Service.parameters = [
[new Inject(SomeService)],
[new Inject(AnotherService), new Optional, new SkipSelf]
];
所有類裝飾器都從TypeDecorator
擴展,這意味着它們可以作為函數調用。 在這種情況下,使用所謂的DSL語法,允許使用Class
輔助函數鏈接裝飾器:
var SomeComponent = Componenent(...).Class(...);
Class
也可單獨使用,它從給定的定義對象構造一個新類,並允許使用數組注釋constructor
方法(類似於Angular 1.x中的內聯數組顯式注釋):
var SomeService = Class({
constructor: [[new Inject(SomeService)], function (someService) {}]
});
在最新的框架版本中不推薦使用Class
助手。 它應該被ES5中的原始函數或第三方類助手替換。 裝飾器支持直接鏈接類函數, Componenent(...)(ComponentClass)
。
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
全局的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.