Angular 4依存注入チュートリアルの6 Injectable装飾器
6974 ワード
目次 Angular 4依存注入チュートリアルの1つ依存注入概要 Angular 4依存注入チュートリアルの2コンポーネントサービス注入 Angular 4依存注入チュートリアルの3 ClassProviderの使用 Angular 4依存注入チュートリアルの4 FactoryProviderの使用 Angular 4依存注入チュートリアルの5 FactoryProvider構成依存オブジェクト Angular 4依存注入チュートリアルの6 Injectableアクセサリ Angular 4依存注入チュートリアルの7 ValueProviderの使用 Angular 4依存注入チュートリアルの8 InjectTokenの使用 読書の心得
このチュートリアルの開発環境と開発言語: Angular 4 + Angular CLI TypeScript
基礎知識
アクセサリーは何ですか.式 式が実行されると、関数 が返される.関数のパラメータはtarge、name、descriptor です.この関数を実行すると、targetオブジェクト を構成するためにdescriptorオブジェクトに戻る可能性があります.
装飾器の分類類装飾器(Class decorators) 属性装飾器(Property decorators) 方法装飾器(Method decorators) パラメータ装飾器(Parameter decorators) TypeScript類装飾器
クラスアクセラレータ宣言:
類装飾器はその名の通り、類を装飾するために使われています.パラメータを受信します. target:Tsuncion-飾られたクラス 一目見た後、気分が悪くなったのではないでしょうか.大丈夫です.すぐに例を挙げましょう.
上記の例では、
Injectable類装飾器使用
Injectable装飾器
更新前のHeroServiceサービス
更新後のHeroServiceサービス
上記のコードが実行されると、次の異常情報が放出されます.
上記の異常情報は、
このコンストラクション関数の入力パラメータは
生成された
上のコードを更新し、保存に成功したら、
__decorate関数
__metadata関数
話があるんだ
@Injectable()は必須ですか?
作成されたサービスが他のオブジェクトに依存しない場合は、
このチュートリアルの開発環境と開発言語:
基礎知識
アクセサリーは何ですか.
装飾器の分類
クラスアクセラレータ宣言:
declare type ClassDecorator = (target: TFunction) =>
TFunction | void
類装飾器はその名の通り、類を装飾するために使われています.パラメータを受信します.
function Greeter(target: Function): void {
target.prototype.greet = function (): void {
console.log('Hello!');
}
}
@Greeter
class Greeting {
constructor() { // }
}
let myGreeting = new Greeting();
myGreeting.greet(); // console output: 'Hello!';
上記の例では、
Greeter
クラスの装飾器を定義するとともに、@Greeter
構文を使用して装飾器を使用します.Injectable類装飾器使用
import { Injectable } from '@angular/core';
@Injectable()
class HeroService {}
Injectable装飾器
Injectable
アクセサリを紹介する前に、HeroComponent
コンポーネントを振り返ってみましょう.@Component({
selector: 'app-hero',
template: `
-
ID: {{hero.id}} - Name: {{hero.name}}
`
})
export class HeroComponent implements OnInit {
heros: Array;
constructor(private heroService: HeroService,
private loggerService: LoggerService) { }
ngOnInit() {
this.loggerService.log('Fetching heros...');
this.heros = this.heroService.getHeros();
}
}
HeroComponent
コンポーネントのngOnInit
ライフサイクルフックでは、ヒーロー情報を取得する前に、対応するデバッグ情報を出力します.実際には、各アプリケーションのコンポーネントにlog
文を追加することを避けるために、log
文をgetHeros()
メソッド内に配置することができます.更新前のHeroServiceサービス
export class HeroService {
heros: Array = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];
getHeros() {
return this.heros;
}
}
更新後のHeroServiceサービス
import { LoggerService } from './logger.service';
export class HeroService {
constructor(private loggerService: LoggerService) { }
heros: Array = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' }
];
getHeros() {
this.loggerService.log('Fetching heros...');
return this.heros;
}
}
上記のコードが実行されると、次の異常情報が放出されます.
Uncaught Error: Can't resolve all parameters for HeroService: (?).
上記の異常情報は、
HeroService
のすべてのパラメータを解析できないことを示しているが、HeroService
サービスの構造関数は以下の通りである.export class HeroService {
constructor(private loggerService: LoggerService) { }
}
このコンストラクション関数の入力パラメータは
loggerService
であり、そのタイプはLoggerService
である.研究を続ける前に、HeroService
が最終的に生成したES5
コードを見てみましょう.var HeroService = (function() {
function HeroService(loggerService) {
this.loggerService = loggerService;
this.heros = [{...}, ...];
}
HeroService.prototype.getHeros = function() {
this.loggerService.log('Fetching heros...');
return this.heros;
};
return HeroService;
}());
生成された
ES5
コードのうち,HeroService
コンストラクタには何のタイプの情報も含まれていないため,Angular Injector(インジェクタ)は正常に動作しないことが分かった.では、HeroService
クラス構造関数のパラメータのタイプ情報をどのように保存しますか?答えを思いついたと思います.もちろんInjectable
の装飾器を使っていますよ.次にHeroService
を更新します.import { Injectable } from '@angular/core';
import { LoggerService } from './logger.service';
@Injectable()
export class HeroService {
// ...
}
上のコードを更新し、保存に成功したら、
http://localhost:4200/
ページで、おなじみの「姿」が表示されます.ID: 11 - Name: Mr. Nice
ID: 12 - Name: Narco
ID: 13 - Name: Bombasto
ID: 14 - Name: Celeritas
ID: 15 - Name: Magneta
HeroService
クラスで生成されたES5
コードを見てみましょう.var HeroService = (function() {
function HeroService(loggerService) {
this.loggerService = loggerService;
this.heros = [{...}, ...];
}
HeroService.prototype.getHeros = function() {
this.loggerService.log('Fetching heros...');
return this.heros;
};
return HeroService;
}());
HeroService = __decorate([__webpack_require__.i(
__WEBPACK_IMPORTED_MODULE_0__angular_core__["c"/* Injectable */
])(), __metadata("design:paramtypes", ...)], HeroService);
__decorate関数
var __decorate = (this && this.__decorate) || function(decorators, target, key, desc) {...};
__metadata関数
var __metadata = (this && this.__metadata) || function(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
return Reflect.metadata(k, v);
};
Injectable
デコレーションを使用していないHeroService
サービスによって生成されたES5
コードよりもHeroService = __decorate(...)
コードが多いことが分かった.簡単に説明しますが、Injectable
アクセラレータでは、コンパイル時にHeroService
サービスコンストラクタのパラメータのタイプ情報をReflect
APIでwindow['__core-js_shared__']
オブジェクトの内部属性に保存します.Injector
がHeroService
オブジェクトを作成すると、Reflect
APIを介して、以前に保存されていたコンストラクタ内のパラメータのタイプ情報が読み込まれ、インスタンス化動作が正しく完了する.興味のある読者は、Angular 4を見ることができます.x修仙の道の中のDecorator( )
章の関連文章.話があるんだ
@Injectable()は必須ですか?
作成されたサービスが他のオブジェクトに依存しない場合は、
Injectable
種類のアクセサリーを使用する必要はありません.しかし、サービスがコンストラクション関数に依存オブジェクトを注入する必要がある場合、Injectable
装飾器を使用する必要がある.ただし、依存オブジェクトがあるかどうかにかかわらず、サービス作成時にInjectable
種類の装飾器を使用することが推奨されます.