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
相关产品推荐
相关产品推荐

