如何统计Angular中*ngFor嵌套*ngIf场景下的显示元素数量
实现方案
方案1:使用Angular纯管道(兼容所有Angular版本,性能最优)
该方案完全符合你不希望在ts文件中直接处理items数组、降低复杂度的要求,同时规避NG0100错误与重复调用的性能问题。
步骤1:创建纯计数管道
创建count-matching.pipe.ts:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'countMatching', pure: true // 默认值,仅输入变更时才会重新计算 }) export class CountMatchingPipe implements PipeTransform { transform(items: any[], condition: (item: any) => boolean): number { if (!items?.length) return 0; // 实际为二维数组时,替换为 return items.flat().filter(condition).length; return items.filter(condition).length; } }
将管道注册到你所在模块的declarations数组中。
步骤2:修改组件ts代码
仅新增判断显示条件的方法,无需修改原有items处理逻辑:
export class ListComponent { @Input('items') items: any[]; constructor() { } // 新增:统一判断条目是否显示的方法,和模板中条件保持一致 protected readonly isItemVisible = (item: any) => item.count < 100; }
步骤3:修改模板代码
<!-- 通过管道计算符合条件的总数,不会被无关事件触发重算 --> <ng-container *ngIf="items | countMatching: isItemVisible as counter"> <p *ngIf="counter">{{counter}} items displayed!</p> <p *ngIf="!counter">Nothing to display!</p> </ng-container> <ng-container *ngFor="let item of items"> <!-- 如果需要顺序序号而非总数,可替换为 let i = index,显示{{i+1}} --> <li *ngIf="isItemVisible(item)">{{counter}}. {{item.title}}</li> </ng-container>
适配可变属性更新场景
如果你修改count属性时使用的是直接修改对象属性的可变更新(未变更items/单个item的引用),只需要把管道的pure属性改为false即可,计数逻辑开销极小,不会产生明显性能损耗。推荐优先使用不可变更新修改count,性能更优。
方案2:Angular 17+ 原生模板语法实现
如果使用Angular 17及以上版本,不需要额外创建管道,直接用@let模板变量实现,代码更简洁:
<!-- 模板内直接计算可见条目,仅依赖变更时才会重算 --> @let visibleItems = items.filter(i => i.count < 100); @let counter = visibleItems.length; <p *ngIf="counter">{{counter}} items displayed!</p> <p *ngIf="!counter">Nothing to display!</p> @for (item of visibleItems; track item.id) { <li>{{counter}}. {{item.title}}</li> }
内容的提问来源于stack exchange,提问作者velediqa
相关产品推荐
相关产品推荐

