首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >覆盖导入模块的组件声明

覆盖导入模块的组件声明
EN

Stack Overflow用户
提问于 2018-01-17 21:04:44
回答 1查看 1.9K关注 0票数 10

你能覆盖第三方模块的组件声明吗?

假设您正在使用一个第三方模块,该模块声明并导出两个组件:

代码语言:javascript
复制
@NgModule({
  exports: [Cmp1, Cmp2]
  declarations: [Cmp1, Cmp2]
})
export class ThirdPartyModule {}

Cmp1的模板:

代码语言:javascript
复制
`<app-cmp2></app-cmp2>`

Cmp2的模板:

代码语言:javascript
复制
`<p>foo</p>`

AppModule导入ThirdPartyModule

代码语言:javascript
复制
@NgModule({
  ...
  imports: [ThirdPartyModule],
  declarations: [AppComponent]
})
export class AppModule {}

AppComponent的模板就是<app-cmp1></app-cmp1>

如何重新声明/覆盖第三方模块的Cmp2实现,以便在Cmp1中呈现的不是Cmp2而是MyCmp2

显然,我需要扩展Cmp2 (或者实现它的接口):

代码语言:javascript
复制
@Component({
  ... // same selector as Cmp2
})
export const MyCmp2 extends Cmp2 {}

我尝试通过DI:{ provide: Cmp2, useClass: MyCmp2 }提供它,但没有起作用。

简单地在app模块中声明它也不会起作用,因为当两个组件匹配同一个选择器时,angular就会抛出异常。这有可能吗?

我的特定用例是重写material的水平步进器的header组件。

EN

回答 1

Stack Overflow用户

发布于 2018-12-11 04:25:36

不可能按照您所描述的方式来实现,因为您要么声明两个具有相同名称的组件,要么根本没有组件。

一种可能的解决方案是将ComponentFactoryResolver与配置服务一起使用。

假设您想在两个不同的模块ComposedWithInner1ModuleComposedWithInner2Module上使用具有不同InnerComponent ( InnerComponent1InnerComponent2)的ComposableComponent

ComposedWithInner1Module定义为:

代码语言:javascript
复制
@NgModule({
  imports: [ComposableComponentModule],
  providers: [
    {
      provide: Config,
      useValue: { component: InnerComponent1 }
    }
  ],
})
export class ComposedWithInner1Module {}

ComposedWithInner2Module定义为:

代码语言:javascript
复制
@NgModule({
  imports: [ComposableComponentModule],
  providers: [
    {
      provide: Config,
      useValue: { component: InnerComponent2 }
    }
  ],
})
export class ComposedWithInner2Module {}

ComposableComponentModule上,您需要说明InnerComponent2InnerComponent1都可以动态注入,这是通过entryComponents属性完成的:

代码语言:javascript
复制
@NgModule({
  declarations: [ComposableComponent],
  exports: [ComposableComponent]
  entryComponents: [InnerComponent2, InnerComponent1]

})
export class ComposableComponentModule {}

然后,ComposableComponent通过注入的Config获取注入的InnerComponentX,并使用ComponentFactoryResolver将其加载到模板中

代码语言:javascript
复制
@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();
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48301883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档