109

@Injectableブートストラップで定義されたサービスがあります。コンストラクター注入を使用せずにサービスのインスタンスを取得したい。使ってみReflectiveInjector.resolveAndCreateましたが、新しいインスタンスを作成しているようです。

私がやろうとしている理由は、多くのコンポーネントから派生した基本コンポーネントがあるからです。サービスにアクセスする必要がありますが、すべての派生コンポーネントにサービスを注入したくないため、サービスを ctor に追加したくありません。

TLDR:私は必要ですServiceLocator.GetInstance<T>()

更新: RC5+ の更新されたコード:コンポーネントで使用するためのインジェクター インスタンスの保存

4

5 に答える 5

87

はい、ReflectiveInjector.resolveAndCreate()接続されていない新しいインジェクター インスタンスを作成します。

AngularsInjectorインスタンスを注入し、そこから目的のインスタンスを取得できます。

constructor(private injector:Injector) {
  injector.get(MyService);
}

また、いくつかのグローバル変数に保存し、Injectorこのインジェクター インスタンスを使用して提供されたインスタンスを取得することもできます。たとえば、https://github.com/angular/angular/issues/4112#issuecomment-153811572

于 2016-05-27T11:42:33.883 に答える
7

別のアプローチは、カスタム デコレーターを定義することで構成されます (CustomInjectable依存性注入のメタデータを設定するには、次のようにします。

export function CustomComponent(annotation: any) {
  return function (target: Function) {

    // DI configuration
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('design:paramtypes', parentTarget);

    Reflect.defineMetadata('design:paramtypes', parentAnnotations, target);

    // Component annotations / metadata
    var annotations = Reflect.getOwnMetadata('annotations', target);
    annotations = annotations || [];
    annotations.push(annotation);
    Reflect.defineMetadata('annotations', annotations, target);
  }
}

独自のメタデータではなく、親コンストラクターからのメタデータを利用します。子クラスで使用できます:

@Injectable()
export class SomeService {
  constructor(protected http:Http) {
  }
}

@Component()
export class BaseComponent {
  constructor(private service:SomeService) {
  }
}

@CustomComponent({
  (...)
})
export class TestComponent extends BaseComponent {
  constructor() {
    super(arguments);
  }

  test() {
    console.log('http = '+this.http);
  }
}

詳細については、この質問を参照してください。

于 2016-05-27T12:12:35.747 に答える