角4依存性学習チュートリアル注入可能な装飾(6)

1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...

学習ディレクトリ

Angular 4 Dependency InjectionチュートリアルにおけるDependency Injectionの紹介
Angular 4 Dependency Injectionチュートリアル2コンポーネントサービスインジェクション
Angular 4 Dependency Injectionチュートリアル3 ClassProviderの使用
4角依存関係の注入チュートリアル4 FactoryProviderの使用
Angular 4依存性注入チュートリアル5 FactoryProvider設定依存オブジェクト
角4依存性注入チュートリアル6注入可能な装飾
Angular 4 Dependency Injectionチュートリアル7 ValueProviderの使用
Angular 4 Dependency Injectionチュートリアル8 InjectTokenの使用

この記事では主に、Angular 4依存性注入注射可能なデコレータの関連コンテンツを紹介します。詳細はこちらを参照してください。

この一連のチュートリアルの開発環境と開発言語:

角度4 +
角度CLI
タイプスクリプト

基礎知識

デコレータとは何ですか?

これは式です。式が実行された後、関数関数の入力パラメータは、targe、name、およびdescriptorです。
この関数を実行した後、ターゲットオブジェクトを設定するためのディスクリプタオブジェクトを返すことができます。

デコレータの分類

クラスデコレータ
プロパティデコレータ
メソッドデコレータ
パラメータデコレータ

TypeScriptクラスデコレータ

クラスデコレータ宣言:


declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => 
TFunction | void

その名前が示すように、クラスをデコレートするためにクラスデコレータが使用されています。 それはパラメータを受け取る:

ターゲット:TFunction – 装飾されるクラス

最初の視力を読んだ後、気分が悪いのではないですか? いいえ、すぐに例を挙げましょう:


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構文を使用しました。

注射可能なクラスのデコレータ使用


import { Injectable } from '@angular/core';
@Injectable()
class HeroService {}

注射可能なデコレータ

注入可能デコレータを導入する前に、HeroComponentコンポーネントを確認しましょう。


@Component({
selector: 'app-hero',
template: `
<ul>
<li *ngFor="let hero of heros">
ID: {{hero.id}} - Name: {{hero.name}}
</li>
</ul>
`
})
export class HeroComponent implements OnInit {
heros: Array<{ id: number; name: string }>;
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: number; name: string }> = [
{ 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: number; name: string }> = [
{ 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クラスコンストラクタのパラメータの型情報をどのように保存しますか? 私はあなたがすでに答えを考えていると信じています – もちろん、注入可能なデコレータを使用しています。 次に、HeroServiceを更新します。


import { Injectable } from '@angular/core';
import { LoggerService } from './logger.service';
@Injectable()
export class HeroService {
// ...
}

上記のコードを更新した後、http:// localhost:4200 / pageに保存が成功すると、使い慣れた "shadow"が表示されます:


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);

__デコレート関数


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);
};

HeroServiceサービスは、未使用のHeroService = __decorate(...)デコレータと比べ、 HeroService = __decorate(...)よりも多くのES5コードを生成していました。 Injectableデコレータを使用すると、HeroServiceサービスコンストラクタ内のパラメータの型情報がReflect APIを介してwindow['__core-js_shared__']オブジェクトの内部プロパティに保存されます。 インジェクタがHeroServiceオブジェクトを作成すると、以前に保存されたコンストラクタ内のパラメータのタイプ情報がReflect APIを介して読み込まれ、インスタンス化操作が正しく完了します。

私は何か言いたいことがある

@Injectable()は必要ですか?

作成されるサービスが他のオブジェクトに依存しない場合は、Injectableクラスデコレータの使用を避けることができます。 しかし、サービスがコンストラクタに依存性を注入する必要がある場合は、注入可能なデコレータを使用する必要があります。 ただし、依存オブジェクトがあるかどうかにかかわらず、サービスを作成するときは、Injectableクラスのデコレータを使用することをお勧めします。

要約

上記はこの記事の内容全体です。私はこの記事の内容が皆の研究に役立つか、角度4を使用することを願っています。ご不明な点がありましたら、メッセージを残してください。


1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...
      この投稿は審査処理中  | 元のサイトへ