web-dev-qa-db-ja.com

Angular 6でサービスを生成するときに、Injectableデコレータで提供された目的は何ですか?

Angular CLIでサービスを生成するとき、Injectableデコレータのデフォルトの「root」で「provided in」プロパティを持つ追加のメタデータが追加されます。

@Injectable({
  providedIn: 'root',
})

提供されたものは正確に何ですか?これにより、アプリケーション全体で「グローバル」タイプのシングルトンサービスのようにサービスを利用できるようになりますが、AppModuleのプロバイダー配列でそのようなサービスを宣言する方がクリーンではないでしょうか?

UPDATE:

特に機能モジュールのみにサービスを提供したい場合は、他の人にとっても、次の段落でそれについての適切な説明を提供しました。

新しいprovidedIn属性を使用して、@Injectable()デコレーター内に直接、プロバイダーを登録する新しい推奨方法があります。 'root'を値またはアプリケーションのモジュールとして受け入れます。 'root'を使用すると、injectableがアプリケーションにシングルトンとして登録され、ルートモジュールのプロバイダーに追加する必要はありません。同様に、providedIn: UsersModuleを使用する場合、injectableは、モジュールのUsersModuleに追加せずに、providersのプロバイダーとして登録されます。 "- https ://blog.ninja-squad.com/2018/05/04/what-is-new-angular-6/

更新2:

さらに調査した結果、providedIn: 'root'を持つことのみが有用であると判断しました

ルートモジュール以外のモジュールでprovideサービスを使用する場合は、フィーチャモジュールのデコレーターでproviders配列を使用することをお勧めします。そうしないと、循環依存関係に悩まされます。ここで興味深い議論が行われます- https://github.com/angular/angular-cli/issues/1017

62
Stefan Zvonar

givenInを使用する場合、注入可能オブジェクトはモジュールのプロバイダーに追加されずに、モジュールのプロバイダーとして登録されます。

Docs から

サービス自体は、CLIが生成したクラスであり、@ Injectableで装飾されています。デフォルトでは、このデコレーターは、サービスのプロバイダーを作成するgivenInプロパティーで構成されます。この場合、providedIn: 'root'は、サービスがルートインジェクターで提供されることを指定します。

28

Angular 6以降、providedIn: 'root'はサービスを提供する最も簡単で効率的な方法です。

  1. サービスは、モジュールのプロバイダー配列に追加する必要のないシングルトンとしてアプリケーション全体で利用可能になります(Angular <= 5など)。
  2. サービスが遅延ロードされたモジュール内でのみ使用される場合、そのモジュールで遅延ロードされます
  3. 使用されない場合、ビルドには含まれません(ツリーが揺れます)。

詳細については、 ドキュメント および NgModule FAQs を読むことを検討してください。

ところで:

  1. アプリケーション全体のシングルトンが必要ない場合は、代わりにプロバイダーのコンポーネントの配列を使用します。
  2. 特定のモジュール以外で他の開発者がサービスを使用しないように範囲を制限する場合は、代わりにプロバイダーのNgModuleの配列を使用します。
16
Mick

givenInはAngularに、ルートインジェクターがサービスのインスタンスの作成を担当することを伝えます。この方法で提供されるサービスは、アプリケーション全体で自動的に利用可能になり、モジュールにリストする必要はありません。

サービスクラスは独自のプロバイダーとして機能するため、@ Injectableデコレータで定義することが必要なすべての登録です。

4
Jawad Farooqi

ドキュメントから

注入可能なデコレータとは何ですか?

クラスをインジェクターが作成できるようにマークします。

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

サービス自体は、CLIが生成したクラスであり、@ Injectable()で装飾されています。

提供されたものは正確に何ですか?

@NgModuleまたは他のInjectorTypeに関連付けるか、このインジェクタブルをほとんどのアプリのアプリケーションレベルのインジェクタである「ルート」インジェクタで提供するように指定することにより、インジェクタを提供するインジェクタを決定します。

providedIn: Type<any> | 'root' | null

providedIn: 'root'

ルートレベルでサービスを提供すると、Angularはサービスの単一の共有インスタンスを作成し、それを要求するクラスに注入します。 @Injectable()メタデータにプロバイダーを登録すると、Angularが、使用されていない場合はコンパイルされたアプリからサービスを削除してアプリを最適化することもできます。

providedIn:モジュール

特定の@NgModuleでサービスを提供するように指定することもできます。たとえば、作成したモジュールをインポートしない限り、アプリケーションがサービスを利用できないようにする場合は、モジュールでサービスを提供するように指定できます

import { Injectable } from '@angular/core';
import { UserModule } from './user.module';

@Injectable({
  providedIn: UserModule,
})
export class UserService {
}

このメソッドは、何も注入しない場合にサービスのツリーシェーキングを有効にするため、推奨されます。

サービスで提供するモジュールを指定できない場合は、モジュール内でサービスのプロバイダーを宣言することもできます。

import { NgModule } from '@angular/core';
import { UserService } from './user.service';

@NgModule({
  providers: [UserService],
})
export class UserModule {
}
2
Nipuna

Documentation によると:

@Injectable()メタデータにプロバイダーを登録すると、Angularが、使用されていない場合はコンパイル済みアプリからサービスを削除してアプリを最適化することもできます。

2
Maarti