You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular动态组件中投影另一个组件?

解决方案:动态创建组件并投影另一个组件到其中

要将ContentComponent投影到动态生成的DynamicComponent内,你需要先获取ContentComponent的渲染根节点,再将这些节点作为投影内容传入DynamicComponent的创建参数中,具体实现如下:

代码实现(Angular 13+)

Angular 13及以上版本可直接通过ViewContainerRef.createComponent创建组件,无需额外依赖ComponentFactoryResolver:

import { Component, AfterViewInit, ViewChild, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
import { ContentComponent } from './content.component';

@Component({
    selector: 'tester',
    template: `
        <p>Tester Component</p>
        <ng-container #cnt></ng-container>
    `
})
export class TesterComponent implements AfterViewInit {

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

    ngAfterViewInit(): void {
        // 临时创建ContentComponent实例,获取其渲染根节点
        const contentCompRef = this.cnt.createComponent(ContentComponent);
        const projectableNodes = contentCompRef.hostView.rootNodes;
        // 销毁临时实例,避免在原容器中残留
        contentCompRef.destroy();

        // 创建DynamicComponent并传入投影节点
        this.cnt.createComponent(DynamicComponent, {
            projectableNodes: [projectableNodes]
        });
    }
}

代码实现(Angular 8及以下)

旧版本需使用ComponentFactoryResolver解析组件工厂:

import { Component, AfterViewInit, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
import { ContentComponent } from './content.component';

@Component({
    selector: 'tester',
    template: `
        <p>Tester Component</p>
        <ng-container #cnt></ng-container>
    `
})
export class TesterComponent implements AfterViewInit {

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

    constructor(private cfr: ComponentFactoryResolver) { }

    ngAfterViewInit(): void {
        // 解析ContentComponent的组件工厂
        const contentFactory = this.cfr.resolveComponentFactory(ContentComponent);
        const contentCompRef = this.cnt.createComponent(contentFactory);
        const projectableNodes = contentCompRef.hostView.rootNodes;
        contentCompRef.destroy();

        // 创建DynamicComponent并传入投影节点
        this.cnt.createComponent(DynamicComponent, {
            projectableNodes: [projectableNodes]
        });
    }
}

关键逻辑说明

  1. 临时生成组件实例:先创建ContentComponent的临时实例,目的是获取它渲染后的根节点集合(rootNodes)
  2. 清理临时实例:获取节点后立即销毁临时实例,避免其留在原容器中干扰DOM结构
  3. 传入投影配置:将根节点数组作为projectableNodes参数传入DynamicComponent的创建配置,这些节点会自动被投影到DynamicComponent的<ng-content>位置

注意事项

  • Angular 8及以下版本需要将ContentComponent添加到模块的entryComponents数组中
  • 确保ContentComponent已在模块的declarations中声明(独立组件无需此操作)

内容的提问来源于stack exchange,提问作者atiyar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 21:20:07