如何在Angular 2中动态添加提供程序到注入器?

Kug*_*gel 9 angular2-di angular

每个组件都可以使用ComponentMetadata中的"providers"属性指定新的Providers.

有没有办法从组件的构造函数动态指定提供程序?

Hie*_*yen 9

我使用useFactory来确定将用于提供的类。我分担为谁关心。

在组件 ts

@Component({
    selector: 'app-chart',
    templateUrl: './chart.component.html',
    styleUrls: ['./chart.component.scss'],
    providers: [
        { provide: DateTimeAdapter, useClass: MomentDateTimeAdapter },
        { provide: OWL_DATE_TIME_FORMATS, useValue: CUSTOM_FORMATS },
        { provide: OwlDateTimeIntl, deps: [SettingService],
            useFactory: (settingsService) => settingsService.getLanguage()
        }
    ]
})
Run Code Online (Sandbox Code Playgroud)

在服务 ts 中获取类实例

@Injectable()
export class SettingService {
    public getLanguage(){
       return this.translate.currentLang == "ko" ? new KoreanIntl() : new DefaultIntl;
    }
}
Run Code Online (Sandbox Code Playgroud)


Lan*_*ley 5

我已经在bootstrap部分完成了它.

bootstrap(AppComponent,[
    provide( RequestOptions, { useClass: DefaultRequestOptions } ),
    provide(Http, { useFactory:
        function(backend, defaultOptions) {
            return new Http(backend, defaultOptions); },
        deps: [XHRBackend, RequestOptions]}),
]);
Run Code Online (Sandbox Code Playgroud)

我猜它也可以在一个组件中完成:

https://angular.io/docs/ts/latest/api/http/Http-class.html

通过将决策添加到工厂函数而不是仅返回相同的对象,可以使其动态化.


Shi*_*ala 5

Below are 3 broader steps you need to follow to implement dynamic providers. Please note i have commented many part of the code so that we focus on the main answer. If you want to see detailed step refer this Angular tutorial

Step 1 :- Create the collection of the providers

Create the collection and you can use the push method to add DI objects dynamically.

var providerscoll:any = [];
providerscoll.push({ provide: "1", useClass: DialogLogger });
providerscoll.push({ provide: "2", useClass: ConsoleLogger });
Run Code Online (Sandbox Code Playgroud)

Step 2 :- Provide the providers collection in "NgModule" .

Please see the Square bracket syntax.

@NgModule({
    // code removed for clarity
    providers: [providerscoll]
})
export class MainModuleLibrary { }
Run Code Online (Sandbox Code Playgroud)

Step 3 :- Get the Injector object in constructor

Get injector object in the constructor using DI and you can then look up using the "Get" method and the token. So if you provide "1" then you get something and if you provide "2" you get something.

// code removed for clarity
import {  Injector } from '@angular/core';
// code removed for clarity
export class CustomerComponent {
constructor(public injector: Injector){
        this.logger = this.injector.get("2");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是动态提供者,这只是使用 Injector 延迟注入。 (2认同)