簡體   English   中英

Angular2在運行時將AppModule的服務注入到依賴的NgModule的組件中嗎?

[英]Angular2 inject a service from AppModule into dependent NgModule's component at runtime?

如果我有:

AppModule imports: [SubModule], providers: [AppProvidedService]

SubModule declarations: [SubComponent]

SubComponent constructor(appProvidedService: AppProvidedService){}

我得到:

Uncaught Can't resolve all parameters for SubComponent: (?).

基本上,這是說注入器無法解析AppProvidedService。

如何構建NgModule,使其依賴於在依賴NgModule的服務中創建的服務?

我嘗試使用OpaqueToken和接口,但是仍然存在相同的問題。 SubModule只是看不到來自父模塊的內容。

最終的需求是擁有一個可以從導入它的應用程序中進行注入的模塊。 這樣,我可以將特定於應用程序的行為注入到通用組件中。

我想通了。 它確實需要OpaqueTokens。

首先,提供一個接口和該接口的OpaqueToken(app-provided.service.interface:

import { OpaqueToken } from "@angular/core";

export interface AppProvidedServiceInterface {
    ...
}

export const SERVICE_INTERFACE = new OpaqueToken("AppProvidedServiceInterface");

在AppModule的提供程序中:

    /*
     * Injection of app-specific behavior into a common module without hard dependencies:
     *
     * This is how you inject a service into a module that is imported
     * and prevent that module from having a hard dependency on the actual
     * implementation.  Use an interface with an OpaqueToken. Then the
     * component that needs it imports it and uses the AppInjector to get the
     * instance.
     */
    {
        provide: SERVICE_INTERFACE,
        useFactory: () => {
            return new AppProvidedService();
        }
    }

並在引導程序中獲取對應用程序注入器的引用並將其存儲...(我們使用一個名為AppInjector的簡單單例類(答案末尾的源代碼)):

platformBrowserDynamic().bootstrapModule(AppModule)
.then((appRef: NgModuleRef<AppComponent>) => {
        AppInjector.getInstance().setInjector(appRef.injector);
    },
    error => console.log(error) // tslint:disable-line
);

然后,在SubModule中要使用注入的東西的類中,必須使用注入器來基於OpaqueToken(sub.component.ts)查找類:

// DO NOT REFERENCE A CONCRETE SERVICE!
private appProvidedService: AppProvidedServiceInterface;

constructor(/* can't inject it here */) {
    // Get the app-specific behavior from the service injected in the application module.
    this.appProvidedService = AppInjector.getInstance().getInjector().get(SERVICE_INTERFACE);
}

現在,您的SubModule具有對接口的引用,而不是具體的實現,AppModule可以通過providers: []注入所需的行為providers: []

AppInjector單例:

import { Injector } from "@angular/core";

export class AppInjector {
    private static instance: AppInjector;
    private injector: Injector;

    constructor() {
        // throw new Error("Singleton - can't instantiate.");        
    }

    public static getInstance() {
        if (!AppInjector.instance) {
            AppInjector.instance = new AppInjector();
        }

        return AppInjector.instance;
    }

    public setInjector(injector: Injector) {
        this.injector = injector;
    }

    public getInjector(): Injector {
        return this.injector;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM