Angular 2
アプリケーションの別のサービスにサービスを挿入する必要があります。
私が推論したドキュメントを読んだ後、最良のアプローチは Factory Provider を使用することです。ただし、次の2つの質問があります。
1)ドキュメントは、2つの「コードセグメント」を持つHeroServiceProvider
クラスの作成を推奨しています。
let heroServiceFactory = (logger: Logger, userService: UserService) => {
return new HeroService(logger, userService.user.isAuthorized);
};
export let heroServiceProvider =
{ provide: HeroService,
useFactory: heroServiceFactory,
deps: [Logger, UserService]
};
私の質問は、クラスが一般的にどのように見えるかです。上記のコードセグメントはどこに追加する必要がありますか?
2)この工場をどのように使用するか、または使用できますか?次のようにインポートする必要があります。
import { heroServiceProvider } from './hero.service.provider';
@Component({
selector: 'my-selector',
template: `
`,
providers: [heroServiceProvider]
})
目的のパラメータ化されたサービスを取得してアクセスするにはどうすればよいですか?
長い検索の後、私はapp_initalizerに注入するのと同じ問題に直面しました、私は以下の解決策を見つけました。これがあなたのシナリオの助けになるかもしれません。
@NgModule({
imports: [ BrowserModule],
...
providers: [
{
provide: HeroService,
useFactory: heroServiceFactory,
deps: [Logger, UserService],
multi: true
}
]
})
export class AppModule {}
export function heroServiceFactory = (logger: Logger, userService: UserService) => {
return new HeroService(logger, userService.user.isAuthorized);
};
@mgmg
の回答に対してコメントするのに十分なポイントがありませんが、ここに役立つ情報があります...
私は自分のアプリでドキュメント(およびこの質問の主題)に記載されているプロバイダーファクトリパターンを使用しましたが、コンパイルでエラーが発生し続けました
シンボル値を静的に解決中にエラーが発生しました。関数呼び出しはサポートされていません。関数またはラムダをエクスポートされた関数への参照に置き換えることを検討してください...
本質的に、ファクトリ依存関係がルートモジュールで使用される場合、すべての依存関係を提供する必要があります。
つまり、@mgmg
の回答で指定されたコードブロックには、厳密に依存サービスが必要です。
import { heroServiceProvider } from './hero.service.provider';
import { UserService } from './user.service';
import { Logger } from './logger.service';
...
@NgModule({
...
providers: [
Logger,
UserService,
heroServiceProvider
// Wrapper for:
//{ provide: HeroService,
// useFactory: (logger: Logger, userService: UserService) => {
// return new HeroService(logger, userService.user.isAuthorized)
// },
// deps: [Logger, UserService]
//};
],
bootstrap: [ AppComponent ]
})
注:angular docs here 、heroServiceProviderはheroes.componentapp.moduleにはなく、LoggerとUserServiceへの参照は不要ですこれら2つの依存関係は、インジェクターツリーの上位から取得されていると思います。
1)質問の最初の部分は簡単です:質問に示すように、提供したスニペットを別のファイルに保持し、コンポーネントにインポートするだけです:
import { heroServiceProvider } from './hero.service.provider';
2)実際の使用に関しては、コンポーネントのサービス関連のコードを実際に変更する必要はありません。元のサービスが注入された場合はそのまま使用し続けます。コンポーネントコンストラクターを変更する必要さえありません。サービスプロバイダーの考え方は、コンポーネントごとにカスタムサービスプロバイダーを用意することで、コンポーネントごとにサービスをカスタマイズでき、ファクトリー関数でコンポーネント固有の初期化を行うことです。コンポーネントのデコレータにサービスプロバイダーをリストすることを忘れないでください。Angularは残りを「自動的に」処理します。
質問1:
クラスは一般的にどのように見えるべきですか?上記のコードセグメントはどこに追加する必要がありますか?
回答:
ヒーローサービスプロバイダーとそのファクトリー機能のコードを含むファイルを作成できます。このファイルには、hero.service.provider.ts
という名前を付けることができます。
そして、ヒーローサービスのコードをhero.service.ts
という名前の別のファイルに記述します。
他の例を参照するには、 Angular Service Providers の使用方法についての記事をご覧ください。
hero.service.provider.ts
ファイル:
import { HeroService } from './hero.service';
import { Logger } from './logger.service';
import { UserService } from './user.service';
let heroServiceFactory = (logger: Logger, userService: UserService) => {
return new HeroService(logger, userService.user.isAuthorized);
};
export let heroServiceProvider =
{ provide: HeroService,
useFactory: heroServiceFactory,
deps: [Logger, UserService]
};
質問2:このファクトリーをどのように使用するべきですか?
回答:
提供したサンプルコードに従って、@Component
デコレーターのプロバイダーフィールドを使用してサービス用にファクトリーを構成し、 サービスを挿入できます クラスコンストラクターまたはAngularインジェクターオブジェクトを使用。
ただし、工場のプロバイダーがこの方法で構成した場合、ツリーの揺れは機能しません。木の揺れが必要な場合は、この Angular tree Shakable Serviceの例をご覧ください 。
import { heroServiceProvider } from './hero.service.provider';
import { HeroService } from './hero.service';
@Component({
selector: 'my-selector',
template: ``,
providers: [heroServiceProvider]
})
export class HeroComponent {
constructor(private heroService: HeroService) { }
}
今日、私は同じ質問に直面し、解決策を見つけました。
1)angular.ioで正確なコードを見つけました。次を参照してください。 https://github.com/angular/angular.io/blob/master/public/docs/_examples/dependency-injection/ts/src /app/heroes/hero.service.provider.ts (2017年3月15日に更新されたリンク)。
このコードから、heroServiceProviderはクラスである必要はありません。
2)app.module.tsでは、@ NgModuleにproviderプロパティがあります。そして、次のようにheroServiceProviderを追加できます:
import { heroServiceProvider } from './hero.service.provider';
...
@NgModule({
...
providers: [
heroServiceProvider
],
bootstrap: [ AppComponent ]
})
そのような@NgModuleでサービスを提供することにより、アプリケーションスコープでサービスを使用できます。