web-dev-qa-db-ja.com

Angular 4:コンストラクターで@Injectが使用されるのはいつですか?

問題の統計

私はAngular 4を学んでおり、@Injectconstructorで使用されており、その理由がわかりません...

コードとソース

Angular 4 Material

コードソース:https://material.angular.io/components/dialog/overview

コードでは、MAT_DIALOG_DATA

constructor(public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
             @Inject(MAT_DIALOG_DATA) public data: any
           ) { }

誰がそれが何を意味し、いつ/どこでこれを行うべきかを詳しく説明していただけますか?

20
Vikas Bansal

@Inject()は、parameterを挿入する必要があることをAngularに知らせるためのmanualメカニズムです。 。

import { Component, Inject } from '@angular/core';
import { ChatWidget } from '../components/chat-widget';

@Component({
  selector: 'app-root',
  template: `Encryption: {{ encryption }}`
})
export class AppComponent {
  encryption = this.chatWidget.chatSocket.encryption;

  constructor(@Inject(ChatWidget) private chatWidget) { }
}

上記では、@Inject(ChatWidget)を呼び出すことで、chatWidgetがシングルトンAngularにclassシンボルChatWidgetに関連付けられるように要求しました。入力にChatWidgetを使用していることに注意することが重要ですandをシングルトンへのreferenceとして。私たちはnotを使用してChatWidgetを使用して何かをインスタンス化します。Angularはそれを舞台裏で行います

から https://angular-2-training-book.rangle.io/handout/di/angular2/inject_and_injectable.html

8
Rahul Singh

MAT_DIALOG_DATAが非工場/クラスの依存関係(構成のstringなど)の場合、通常は@Injectを使用します。

InjectionTokenも確認してください: https://angular.io/guide/dependency-injection#injectiontoken

非クラス依存関係のプロバイダートークンを選択する1つのソリューションは、InjectionTokenを定義して使用することです


ここにプランカーがあります: http://plnkr.co/edit/GAsVdGfeRpASiBEy66Pu?p=preview

これらの場合に@Injectを削除すると、

ComponentNameのすべてのパラメーターを解決できません:(?)

7
eko

AngularのIoCコンテナは、コンストラクターの型宣言を使用して、コンストラクターパラメーターに注入するオブジェクトを決定します。

あなたの例では、「_public data: any_」パラメータは「any」として定義されているため、その型宣言によって決定できませんでした。この問題を解決するには、「@Inject(MAT_DIALOG_DATA)」デコレーターを使用して、「data」パラメーターに挿入する必要があるオブジェクトについてIoCコンテナーに通知する必要があります。

また、あなたの例では、「_@Inject_」デコレータをInjectionTokenと共に使用して、物事をもう少し複雑にします:)

InjectionTokenは、実際にはIoCコンテナが他のクラスに注入するために使用するオブジェクトに名前を付けるために使用されるクラスです。通常、IoCインジェクションのトークンとして任意のクラス名を使用できます(例では「_MatDialogRef<DialogOverviewExampleDialog>_」など)。これは正常に機能します。しかし、UnitTestsの記述を開始すると、クラスに注入するために実際のオブジェクトの代わりにMockオブジェクトを使用する必要があることに気付き、トークンとして実際のクラス名を使用すると、それを行うことができません。

この問題を解決するには、トークン名としてInterfacesを使用できますが、これは実際には正しいソリューションですが、JavaScriptはインターフェイスをサポートしないため、トークンとしてInterface名を使用できません。 Interface定義が含まれています。

このすべての結果として、InjectionTokenを使用する必要があります。 InjectionTokenを使用すると、コンストラクタに任意のオブジェクトを注入できます。モジュールで宣言し、注入する実際のクラスにマップするだけです。これにより、生産コードとテストコードに異なるクラスを使用できます。

3
Yildiray Meric