Angular 2:在DOM中如何插入一个动态组件作为容器的子组件?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (506)

是否有一种方法可以将组件动态插入为child中的DOM标记?

有大量的示例可以将动态组件插入到给定的同级中。ViewContainerRef的标记,例如(从RC3开始):

@Component({
  selector: '...',
  template: '<div #placeholder></div>'
})
export class SomeComponent {
  @ViewChild('placeholder', {read: ViewContainerRef}) placeholder;

  constructor(private componentResolver: ComponentResolver) {}

  ngAfterViewInit() {
    this.componentResolver.resolveComponent(MyDynamicComponent).then((factory) => {
        this.componentRef = this.placeholder.createComponent(factory);
    });
  }
}

但是这会生成一个DOM,类似于:

<div></div>
<my-dynamic-component></my-dynamic-component>

输出:

<div>
    <my-dynamic-component></my-dynamic-component>
</div>

使用SomeComponentViewContainerRef有相同的结果,它仍然插入生成的组件作为同级,而不是一个子。如果模板是空的,并且动态组件被插入到模板中(在组件选择器标记中),我会接受这个解决方案。

提问于
用户回答回答于

相关代码:

@Component({
  selector: 'my-app',
  template: `<div><ng-template #container></ng-template></div>`
})
export class AppComponent implements OnInit {

    @ViewChild('container', {read: ViewContainerRef}) viewContainer: ViewContainerRef;

    constructor(private compiler: Compiler) {}

    ngOnInit() {
      this.createComponentFactory(MyDynamicComponent).then(
        (factory: ComponentFactory<MyDynamicComponent>) => this.viewContainer.createComponent(factory),
        (err: any) => console.error(err));
    }

    private createComponentFactory(/*...*/) {/*...*/}

}

似乎<ng-container #placeholder></ng-container>也在工作(替换ng-template通过ng-container)。

用户回答回答于

以下是代码:

@Directive({
    selector: '[mydirective]'
})
export class MyDirectiveDirective {
    constructor(
        private cfResolver: ComponentFactoryResolver,
        public vcRef: ViewContainerRef,
        private renderer: Renderer2
    ) {}

    public appendComponent() {
        const factory = 
        this.cfResolver.resolveComponentFactory(MyDynamicComponent);
        const componentRef = this.vcRef.createComponent(factory);
        this.renderer.appendChild(
           this.vcRef.element.nativeElement,
           componentRef.injector.get(MyDynamicComponent).elRef.nativeElement
        );
    }
}

扫码关注云+社区

领取腾讯云代金券