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

Angular 17:如何在TS文件中判断各ng-content是否为空?

解决Angular卡片组件判断ng-content是否为空的问题

方法一:通过容器元素检测内容

ng-content本身无法直接被查询,我们可以给每个ng-content所在的父容器添加模板引用变量,通过检测容器内的实际内容来判断是否为空。

1. 修改模板,添加模板引用变量

<mat-card>
  <mat-card-header>
    <mat-card-title #titleContainer>
        <ng-content select="[card-title]"></ng-content>
    </mat-card-title>

    <mat-card-subtitle #subtitleContainer>
        <ng-content select="[card-subtitle]"></ng-content>
    </mat-card-subtitle>
  </mat-card-header>

  <mat-card-content #contentContainer>
    <ng-content select="[card-content]"></ng-content>
  </mat-card-content>

  <mat-card-actions #actionsContainer>
    <ng-content select="[card-actions]"></ng-content>
  </mat-card-actions>
</mat-card>

2. 在组件类中实现检测逻辑

import { Component, ViewChild, ElementRef, AfterContentInit } from '@angular/core';

@Component({
  selector: 'app-custom-card',
  templateUrl: './custom-card.component.html'
})
export class CustomCardComponent implements AfterContentInit {
  @ViewChild('titleContainer') titleContainer!: ElementRef;
  @ViewChild('subtitleContainer') subtitleContainer!: ElementRef;
  @ViewChild('contentContainer') contentContainer!: ElementRef;
  @ViewChild('actionsContainer') actionsContainer!: ElementRef;

  hasTitle = false;
  hasSubtitle = false;
  hasContent = false;
  hasActions = false;

  ngAfterContentInit(): void {
    this.hasTitle = this.hasValidContent(this.titleContainer);
    this.hasSubtitle = this.hasValidContent(this.subtitleContainer);
    this.hasContent = this.hasValidContent(this.contentContainer);
    this.hasActions = this.hasValidContent(this.actionsContainer);
  }

  // 检测容器内是否有非空白的有效内容
  private hasValidContent(container: ElementRef): boolean {
    const element = container.nativeElement;
    return Array.from(element.childNodes).some(node => {
      if (node.nodeType === Node.TEXT_NODE) {
        return node.textContent?.trim().length > 0;
      }
      return node.nodeType === Node.ELEMENT_NODE;
    });
  }
}

这种方法可以同时检测投影的元素内容和纯文本内容,适用性更广。


方法二:通过ContentChildren查询投影元素

如果你的投影内容都是带有指定属性的元素(比如<div card-title>标题</div>),可以直接用ContentChildren查询这些元素的数量来判断是否为空。

组件类代码

import { Component, ContentChildren, QueryList, AfterContentInit, ElementRef } from '@angular/core';

@Component({
  selector: 'app-custom-card',
  templateUrl: './custom-card.component.html'
})
export class CustomCardComponent implements AfterContentInit {
  @ContentChildren('[card-title]') titleElements!: QueryList<ElementRef>;
  @ContentChildren('[card-subtitle]') subtitleElements!: QueryList<ElementRef>;
  @ContentChildren('[card-content]') contentElements!: QueryList<ElementRef>;
  @ContentChildren('[card-actions]') actionsElements!: QueryList<ElementRef>;

  hasTitle = false;
  hasSubtitle = false;
  hasContent = false;
  hasActions = false;

  ngAfterContentInit(): void {
    this.hasTitle = this.titleElements.length > 0;
    this.hasSubtitle = this.subtitleElements.length > 0;
    this.hasContent = this.contentElements.length > 0;
    this.hasActions = this.actionsElements.length > 0;
  }
}

注意:这种方法只能检测到带有指定属性的元素,无法识别直接投影的纯文本(比如仅投影无属性的纯文本内容时无法检测)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 00:52:43