24

(DI) 依存性注入が Angular2 でどのように機能するかを理解しようとしています。コンポーネントにサービス/クラスを注入しようとするたびに、多くの問題/問題に遭遇しました。

さまざまなグーグル記事からproviders: []、コンポーネント構成で使用するか@Inject()、コンストラクターで使用するか、bootstrap(app, [service])? @injectableまた、いくつかの記事でデコレータ を配置する必要があることも見てきました。

例: Http を挿入するにはimport{Http}、Http をプロバイダーに入れるだけで済みますが、FormBuilder の場合は@Inject()、コンストラクターで使用する必要があります。

いつ何を使用するかについての経験則はありますか? コードスニペットの例をいくつか教えてください。ありがとうございました :-)

4

5 に答える 5

17

一般的な質問、TL;DRバージョン


@注入可能()

  • typescript装飾されたクラスが持っていることを伝えるデコレーターでありdependencies、このクラスが他のクラスに注入できることを意味するものではありません。

  • importedそして、TypeScript は、依存関係を使用して、構築時に必要なメタデータを装飾されたクラスに注入する必要があることを理解します。

ブートストラップ(アプリ、[サービス])

  • bootstrap() は、ブートストラップ時にアプリケーションのルート インジェクターを作成します。これは、作成時にインジェクターに直接渡される 2 番目の引数としてプロバイダーのリストを受け取ります。

  • のような多くの場所で使用されるサービスを使用してアプリケーションをブートストラップします。これは、クラス構成Httpに書き込む必要がないことも意味します。providers: [Http]

プロバイダー: [サービス]

  • プロバイダーは、すべてのサービスの引数を に渡す作業も行いますInjector

  • サービスが提供されていない場合は、プロバイダーにサービスを配置しますbootstrap()。そして、いくつかの場所でのみ必要です。

@注入()

  • このようなサービスを実際に注入する機能であるデコレーターでもあります
    constructor(@Inject(NameService) nameService)
  • しかし、TS を使用する場合は、これだけconstructor(nameService: NameService)で済み、typescript が残りを処理します。

参考文献

お役に立てれば。:)

于 2016-03-20T07:30:53.960 に答える
4

プロバイダーを使用する必要があります: []

依存性注入でインスタンスを作成できるようにするには、これらのクラス (または他の値) のプロバイダーをどこかに登録する必要があります。

プロバイダーを登録する場所によって、作成される値の範囲が決まります。Angulars DI は階層的です。
ツリーのルートにプロバイダーを登録する場合


>=RC.5

@NgModule({
  providers: [/*providers*/]
  ...
})

または遅延ロードされたモジュールの場合

static forRoot(config: UserServiceConfig): ModuleWithProviders {
  return {
    ngModule: CoreModule,
    providers: [
      {provide: UserServiceConfig, useValue: config }
    ]
  };
}

<=RC.4

(bootstrap(AppComponent, [Providers})または@Component(selector: 'app-component', providers: [Providers])(ルート コンポーネント)


インスタンスを要求するすべてのコンポーネントとサービスが同じインスタンスを取得します。

プロバイダーが子コンポーネントの 1 つに登録されている場合、このコンポーネントの子孫に対して新しい (別の) インスタンスが提供されます。

コンポーネントが (コンストラクターのパラメーターによって) インスタンスを要求する場合、DI はコンポーネント ツリーを (リーフからルートに向かって) 「上向き」に検索し、最初に見つかったプロバイダーを取得します。このプロバイダーのインスタンスが以前に作成されている場合は、このインスタンスが使用されます。それ以外の場合は、新しいインスタンスが作成されます。

@注入()

コンポーネントまたはサービスが DI からの値を要求する場合

constructor(someField:SomeType) {}

DI はタイプでプロバイダを検索しますSomeType@Inject(SomeType)が追加された場合

constructor(@Inject(SomeType) someField:SomeType) {}

DI は、 に渡されたパラメータによってプロバイダを検索します@Inject()。上記の例では、渡されたパラメーターは@Inject()パラメーターの型と同じであるため、@Inject(SomeType)冗長です。

ただし、構成設定を挿入するなど、動作をカスタマイズしたい場合があります。

constructor(@Inject('someName') someField:string) {}

string複数の構成設定が登録されている場合、タイプだけでは特定の構成設定を区別するのに十分ではありません。
構成値は、プロバイダーとして次のように登録する必要があります


>=RC.5

@NgModule({
  providers: [{provide: 'someName', useValue: 'abcdefg'})]
  ...
})
export class AppModule {}

<=RC.4

bootstrap(AppComponent, [provide('someName', {useValue: 'abcdefg'})])

@Inject()したがって、コンストラクターが次のようにFormBuilder見える場合は必要ありません

constructor(formBuilder: FormBuilder) {}
于 2016-03-20T07:34:35.407 に答える