如何将组件动态添加到服务中的另一个组件

Posted

技术标签:

【中文标题】如何将组件动态添加到服务中的另一个组件【英文标题】:How to dynamically add component to another component in service 【发布时间】:2020-01-05 22:53:52 【问题描述】:

我将动态组件到服务中的另一个组件,首先在服务工厂内部两个组件,我创建了可以访问 ViewContainer 的组件。但是无法创建组件!

服务:

@Injectable(
    providedIn: 'root'
)
export class ModalService 

    componentRef: ComponentRef<ModalTemplateComponent>;

    constructor(private _modalService: BsModalService,
                private resolver: ComponentFactoryResolver,
                private injector: Injector) 
    

    open(componentType: any) 

        const contentFactory = this.resolver
            .resolveComponentFactory(componentType);

        const templateFactory = this.resolver
            .resolveComponentFactory(ModalTemplateComponent);

        const componentRef = templateFactory.create(this.injector);
        componentRef.instance.container.createComponent(contentFactory);

this._modalService.show(componentRef.componentType, class: 'modal-lg', initialState: data: test:true);

    

组件:

    selector: 'lib-modal-template',
    template: `
        <h1>title</h1>
        <ng-container #container>
        </ng-container>
    `,
    styleUrls: ['./modal-template.component.css']
)
export class ModalTemplateComponent implements OnInit 

        title:string;
    @ViewChild('container', read: ViewContainerRef, static: true) container: ViewContainerRef;

示例:

this._modalService.open(NewUserForm,...);

【问题讨论】:

【参考方案1】:

首先,此行将创建ModalTemplateComponent 的新实例,而不是componentRef,因此您不在同一个实例上工作。

this._modalService.show(componentRef.componentType, class: 'modal-lg', initialState: data: test:true);

我做了一些调整(使用ngComponentOutlet),它会按你的预期工作:

模态服务

@Injectable(
  providedIn: 'root'
)
export class ModalService 

  constructor(private _modalService: BsModalService,
    private resolver: ComponentFactoryResolver,
    private injector: Injector) 
  

  open(componentType: any) 

    const ref = this._modalService.show(ModalTemplateComponent, class: 'modal-lg', initialState: data: test:true);

    (ref.content as ModalTemplateComponent).componentType = componentType;

  


模态模板组件

@Component(
  selector: 'app-modal-template',
  template: `
  <h1>title</h1>
  <ng-container *ngComponentOutlet="componentType">
  </ng-container>
  `,
  styleUrls: ['./modal-template.component.css']
)
export class ModalTemplateComponent implements OnInit 
  title: string = 'modal-template';

  @Input() componentType: any;

  constructor()  

  ngOnInit() 
  


在线演示:https://stackblitz.com/edit/angular-1srnej?file=src%2Fapp%2Fmodal.service.ts

=================================

如果您想使用动态组件实例,我们可以使用以下解决方案:

模态模板组件

@Component(
  selector: 'app-modal-template',
  template: `
  <h1>title</h1>
  <ng-container #container>
  </ng-container>
  `,
  styleUrls: ['./modal-template.component.css']
)
export class ModalTemplateComponent implements OnInit, OnDestroy 
  title: string = 'modal-template';
  component: any;
  componentRef: ComponentRef<any>;
  @Input() set componentType(c: any) 
    this.component = c;

    this.renderContent();
  

  @ViewChild('container', 
    read: ViewContainerRef,
    static: true
  ) container: ViewContainerRef;

  constructor()  

  ngOnInit() 
  
  renderContent() 
    this.container.clear();
    const injector = this.container.injector;
    const cfr = injector.get(ComponentFactoryResolver);

    const componentFactory = cfr.resolveComponentFactory(this.component);

    const componentRef = this.container.createComponent<any>(componentFactory);

    componentRef.instance.content = 'content from ' + this.title;

    this.componentRef = componentRef;

  
  ngOnDestroy() 
    if (this.componentRef) 
      this.componentRef.destroy();
    
  

AlertContentComponent

export class AlertContentComponent implements OnInit 
  @Input() content = '';
  constructor()  

  ngOnInit() 
  


演示:https://stackblitz.com/edit/angular-ythykh?file=src%2Fapp%2Fmodal-template%2Fmodal-template.component.ts

【讨论】:

谢谢,如何在警报组件中访问模板组件formGroup? 如果你想访问它,你可以动态渲染Alert Component而不是使用ngComponentOutlet 等一下,我给你新建一个例子 @Allahyar 已更新 stackblitz.com/edit/… 你可以创建新帖子,我稍后再尝试。问候

以上是关于如何将组件动态添加到服务中的另一个组件的主要内容,如果未能解决你的问题,请参考以下文章

如何动态地将组件作为子组件添加到指令中?

如何将样式化组件作为属性添加到 TypeScript 中的另一个样式化组件?

如何从 Blazor 中的另一个组件重新渲染一个组件?

如何在 Ajax 请求期间在 JSF2 中动态添加组件

如何将 VueJS 组件动态添加到打包中?

如何以编程/动态方式将组件添加到 p:dataTable facet