Angular ngFor列表过滤空值:*ngIf无效问题排查与解决
解决Angular列表渲染空项问题
问题分析
你现在碰到的问题很典型:虽然用*ngIf隐藏了空内容的<div>,但*ngFor还是会为每个空属性/动作项生成<li>标签,导致列表里出现空行。根源在于你把判断逻辑放在了<div>上,而不是<li>这个列表项本身。
两种可行的解决方案
方案1:直接在<li>上添加判断逻辑
把*ngIf移到<li>元素上,这样不符合条件的项根本不会被渲染出来。如果你的Angular版本支持同一个元素上同时用*ngFor和*ngIf,可以直接这么写:
<h6>Attributes</h6> <ul> <li *ngFor="let item of card.responsibilities" *ngIf="item.attribute"> <div>{{item.attribute}}</div> </li> </ul> <h6>Actions</h6> <ul> <li *ngFor="let item of card.responsibilities" *ngIf="item.action"> <div>{{item.action}}</div> </li> </ul>
如果遇到版本不兼容的情况(比如旧版Angular不允许同一个元素上用两个结构型指令),用<ng-container>来做循环容器,把*ngIf放在<li>上就行:
<h6>Attributes</h6> <ul> <ng-container *ngFor="let item of card.responsibilities"> <li *ngIf="item.attribute"> <div>{{item.attribute}}</div> </li> </ng-container> </ul> <h6>Actions</h6> <ul> <ng-container *ngFor="let item of card.responsibilities"> <li *ngIf="item.action"> <div>{{item.action}}</div> </li> </ng-container> </ul>
方案2:提前在组件里过滤数据
如果不想在模板里写太多逻辑,可以在组件的TS代码里提前把有效数据过滤出来,模板直接渲染过滤后的数组,这样更简洁:
组件TS代码:
export class YourCardComponent { card = { /* 你的卡片数据 */ }; // 过滤出有值的属性 get validAttributes() { return this.card.responsibilities.filter(item => !!item.attribute); } // 过滤出有值的动作 get validActions() { return this.card.responsibilities.filter(item => !!item.action); } }
模板代码:
<h6>Attributes</h6> <ul> <li *ngFor="let item of validAttributes"> <div>{{item.attribute}}</div> </li> </ul> <h6>Actions</h6> <ul> <li *ngFor="let item of validActions"> <div>{{item.action}}</div> </li> </ul>
为什么原来的写法没用?
之前你把*ngIf放在<div>上,只是隐藏了<div>的内容,但<li>作为列表项已经被*ngFor渲染出来了,所以页面上会有空的列表项占位。只有把判断逻辑提到<li>或者更早的层级,才能彻底避免空项的生成。
内容的提问来源于stack exchange,提问作者Thinker
相关产品推荐
相关产品推荐

