web-dev-qa-db-ja.com

Angular 2コンポーネントに条件付きでサービスを注入する

例:

2つのサービスがあります

1)one.service.ts

2)two.service.ts

そして、私はコンポーネントを持っています-dashboard.component.ts

import { Component, ViewEncapsulation, Inject } from '@angular/core';
import { OneService } from '../services/one.service';
import { TwoService } from '../services/two.service';

@Component({
  selector: 'dashboard',
  encapsulation: ViewEncapsulation.Emulated,
  styleUrls: ['./dashboard.less'],
  templateUrl: './dashboard.html'
})
export class DashboardComponent {
    constructor() {
       // Here how do I get service instance based on some this condition.
         if(true) {
             /* Service **one.service.ts** to be injected */
         } else {
             /* Service **two.service.ts** to be injected */    
         }

    }
}
14
Ajey

Injectorを使用できます

import { Injector } from '@angular/core'  
...
constructor(private injector: Injector){ 

  if(true) {
    this.oneService = <OneService>this.injector.get(OneService);
  } else {
    this.twoService = <TwoService>this.injector.get(TwoService);
  }
}

@MeirionHughesが言及したように、これはサービスロケーターパターンと呼ばれます。

この手法は、サービスロケータパターンの例です。

この方法は避けてください本当に必要な場合を除きます。ここにあるような不注意なグラブバッグアプローチを奨励します。説明、理解、およびテストすることは困難です。コンストラクタを調べても、このクラスに何が必要か、何をするかはわかりません。独自のコンポーネントだけでなく、任意の祖先コンポーネントからサービスを取得できます。あなたはそれが何をするかを発見するために実装を精査することを強いられます。

フレームワーク開発者は、一般的かつ動的にサービスを取得する必要がある場合に、このアプローチをとることがあります。

ソース: https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#explicit-injector

また、前述のように、これらのインジェクターを別のサービスで取得し、このサービスをコンポーネントにインジェクトでき​​ます。

19
eko