每个组件都可以Provider
使用其providers
in 中的属性指定 new ComponentMetadata
。
有没有办法从constructor
组件中动态指定提供者?
每个组件都可以Provider
使用其providers
in 中的属性指定 new ComponentMetadata
。
有没有办法从constructor
组件中动态指定提供者?
我使用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()
}
]
})
在服务中 ts 获取类实例
@Injectable()
export class SettingService {
public getLanguage(){
return this.translate.currentLang == "ko" ? new KoreanIntl() : new DefaultIntl;
}
}
以下是实施动态提供程序需要遵循的 3 个更广泛的步骤。请注意,我已经评论了代码的许多部分,以便我们专注于主要答案。如果您想查看详细步骤,请参阅此Angular 教程
第 1 步:- 创建提供者的集合
创建集合,您可以使用 push 方法动态添加 DI 对象。
var providerscoll:any = [];
providerscoll.push({ provide: "1", useClass: DialogLogger });
providerscoll.push({ provide: "2", useClass: ConsoleLogger });
第 2 步:- 在“NgModule”中提供提供者集合。
请参阅方括号语法。
@NgModule({
// code removed for clarity
providers: [providerscoll]
})
export class MainModuleLibrary { }
第 3 步:- 在构造函数中获取 Injector 对象
使用 DI 在构造函数中获取注入器对象,然后您可以使用“Get”方法和令牌进行查找。因此,如果您提供“1”,那么您会得到一些东西,如果您提供“2”,那么您会得到一些东西。
// 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");
}
}
我已经在引导部分完成了。
bootstrap(AppComponent,[
provide( RequestOptions, { useClass: DefaultRequestOptions } ),
provide(Http, { useFactory:
function(backend, defaultOptions) {
return new Http(backend, defaultOptions); },
deps: [XHRBackend, RequestOptions]}),
]);
我猜它也可以在组件中完成:
https://angular.io/docs/ts/latest/api/http/Http-class.html
您可以通过将决策添加到工厂函数中来使其动态化,而不仅仅是返回相同的对象。
有一种方法可以使用创建组件ViewContainerRef
,其中允许通过injector
,所以我想这应该是可能的,但仅限于动态创建组件:
创建注入器:
static create(options: {providers: StaticProvider[], parent?: Injector, name?: string}): Injector;
// @param injector The injector to use as the parent for the new component.
abstract createComponent<C>(
componentFactory: ComponentFactory<C>, index?: number, injector?: Injector,
projectableNodes?: any[][], ngModule?: NgModuleRef<any>): ComponentRef<C>;
伪代码:
class FooComponent {
constructor(
private readonly injector: Injector,
private readonly viewContainer: ViewContainerRef){
const customInjector = this.injector.create({ providers: [FooService], parent: injector });
this.viewContainer.createComponent(componentFactory, 0, customInjector );
...
}
}
或者类似地使用来自Angular CDK的 Portal 。