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

Angular组件如何根据ng-content内容是否非空渲染不同模板

实现Angular独立组件的hasNonEmptyTextContent方法

核心思路

通过@ContentChild获取投影内容的DOM元素引用,在内容初始化完成后提取并处理文本内容,判断是否包含非空白字符。同时使用ng-container和ng-template避免生成多余DOM节点。

组件类实现

import { Component, ContentChild, ElementRef, AfterContentInit, ChangeDetectorRef, AfterContentChecked } from '@angular/core';

@Component({
  selector: 'app-custom-component',
  standalone: true,
  template: `
    <ng-container *ngIf="hasNonEmptyText; else defaultContent">
      <div class="formatted-wrapper">
        <ng-content #projectedContent></ng-content>
      </div>
    </ng-container>

    <ng-template #defaultContent>
      <span class="default-text">默认文本</span>
    </ng-template>
  `,
  styles: [`
    .formatted-wrapper {
      padding: 8px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }
    .default-text {
      color: #999;
    }
  `]
})
export class CustomComponent implements AfterContentInit, AfterContentChecked {
  @ContentChild('projectedContent', { read: ElementRef }) projectedContent!: ElementRef<HTMLElement>;
  hasNonEmptyText = false;

  constructor(private cdr: ChangeDetectorRef) {}

  ngAfterContentInit(): void {
    this.hasNonEmptyText = this.hasNonEmptyTextContent();
  }

  // 处理动态变化的投影内容(可选)
  ngAfterContentChecked(): void {
    const currentState = this.hasNonEmptyTextContent();
    if (currentState !== this.hasNonEmptyText) {
      this.hasNonEmptyText = currentState;
      this.cdr.detectChanges();
    }
  }

  private hasNonEmptyTextContent(): boolean {
    if (!this.projectedContent?.nativeElement) return false;
    // 提取文本并去除所有首尾空白字符
    const rawText = this.projectedContent.nativeElement.textContent ?? '';
    // 判断处理后的文本是否非空
    return rawText.trim().length > 0;
  }
}

关键细节说明

  1. 获取投影内容:给ng-content添加模板变量#projectedContent,通过@ContentChild获取其ElementRef,确保能直接访问投影内容的DOM节点。
  2. 文本判断逻辑:
    • 使用textContent获取投影内容的所有文本(包括子元素的文本)
    • 调用trim()去除首尾的空格、换行、制表符等空白字符
    • 通过判断处理后的文本长度是否大于0,确定是否为非空内容
  3. 避免多余DOM:使用ng-container和ng-template作为条件渲染的容器,不会在DOM中生成额外的节点。
  4. 动态内容处理:如果投影内容是动态变化的(比如绑定的异步数据),实现AfterContentChecked钩子,实时更新状态并触发变更检测。

使用示例

<!-- 场景1:包含非空文本 -->
<app-custom-component>
  这是需要格式化展示的内容
</app-custom-component>

<!-- 场景2:仅包含空白字符(空格、换行等) -->
<app-custom-component>
  
</app-custom-component>

<!-- 场景3:完全空的投影内容 -->
<app-custom-component></app-custom-component>

注意事项

  • 如果投影内容包含Angular组件,textContent会获取该组件渲染后的文本内容,符合需求逻辑。
  • 若需要排除特定元素的文本(比如某些装饰性元素),可以在hasNonEmptyTextContent方法中进一步过滤DOM节点,例如通过querySelector排除特定类名的元素后再提取文本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:43:09