你能覆盖第三方模块的组件声明吗?
假设您正在使用一个第三方模块,该模块声明并导出两个组件:
@NgModule({
exports: [Cmp1, Cmp2]
declarations: [Cmp1, Cmp2]
})
export class ThirdPartyModule {}Cmp1的模板:
`<app-cmp2></app-cmp2>`Cmp2的模板:
`<p>foo</p>`AppModule导入ThirdPartyModule
@NgModule({
...
imports: [ThirdPartyModule],
declarations: [AppComponent]
})
export class AppModule {}AppComponent的模板就是<app-cmp1></app-cmp1>。
如何重新声明/覆盖第三方模块的Cmp2实现,以便在Cmp1中呈现的不是Cmp2而是MyCmp2
显然,我需要扩展Cmp2 (或者实现它的接口):
@Component({
... // same selector as Cmp2
})
export const MyCmp2 extends Cmp2 {}我尝试通过DI:{ provide: Cmp2, useClass: MyCmp2 }提供它,但没有起作用。
简单地在app模块中声明它也不会起作用,因为当两个组件匹配同一个选择器时,angular就会抛出异常。这有可能吗?
我的特定用例是重写material的水平步进器的header组件。
发布于 2018-12-11 04:25:36
不可能按照您所描述的方式来实现,因为您要么声明两个具有相同名称的组件,要么根本没有组件。
一种可能的解决方案是将ComponentFactoryResolver与配置服务一起使用。
假设您想在两个不同的模块ComposedWithInner1Module和ComposedWithInner2Module上使用具有不同InnerComponent ( InnerComponent1或InnerComponent2)的ComposableComponent。
ComposedWithInner1Module定义为:
@NgModule({
imports: [ComposableComponentModule],
providers: [
{
provide: Config,
useValue: { component: InnerComponent1 }
}
],
})
export class ComposedWithInner1Module {}ComposedWithInner2Module定义为:
@NgModule({
imports: [ComposableComponentModule],
providers: [
{
provide: Config,
useValue: { component: InnerComponent2 }
}
],
})
export class ComposedWithInner2Module {}在ComposableComponentModule上,您需要说明InnerComponent2或InnerComponent1都可以动态注入,这是通过entryComponents属性完成的:
@NgModule({
declarations: [ComposableComponent],
exports: [ComposableComponent]
entryComponents: [InnerComponent2, InnerComponent1]
})
export class ComposableComponentModule {}然后,ComposableComponent通过注入的Config获取注入的InnerComponentX,并使用ComponentFactoryResolver将其加载到模板中
@Component({
selector: 'prl-column-header-extras',
template: '<p> I'll be substituted by InnerComponent2 or InnerComponent1 </p>'
})
export class ComposableComponent implements OnInit {
constructor(
private config: Config,
private componentFactoryResolver: ComponentFactoryResolver
) {}
ngOnInit() {
const comp = this.componentFactoryResolver.resolveComponentFactory(
this.config.component
);
this.viewContainerRef.clear();
const ref = this.viewContainerRef.createComponent(comp);
ref.changeDetectorRef.markForCheck();
}
}https://stackoverflow.com/questions/48301883
复制相似问题