【问题标题】: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,...);

【问题讨论】:

    标签: angular angular-dynamic-components


    【解决方案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/…
    • 你可以创建新帖子,我稍后再尝试。问候
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    相关资源
    最近更新 更多