Angular技术问题:如何在*ngFor外部获取过滤器管道处理后的结果数量
解决Angular中*ngFor外部获取过滤后结果数量的问题
嘿,我遇到过一模一样的困扰,给你两个亲测有效的解决方案:
方案1:把过滤逻辑移到组件类中(推荐)
这种方式更符合Angular的最佳实践,逻辑更清晰,还能轻松拿到过滤后的数量。
首先在组件的.ts文件里,把管道的过滤逻辑迁移过来,用RxJS操作符处理:
import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Component({ // 你的组件元数据(selector、templateUrl等) }) export class YourPostingsComponent implements OnInit { filteredPostings$!: Observable<any[]>; resultsNumber$!: Observable<number>; // 假设你的原始数据来自服务,替换成你实际的数据源 constructor(private postingService: PostingService) {} ngOnInit(): void { // 获取原始的帖子数据Observable const originalPostings$ = this.postingService.getPostings(); // 应用和postingsFilter管道一致的过滤逻辑 this.filteredPostings$ = originalPostings$.pipe( map(postings => postings.filter(posting => { // 这里写你postingsFilter管道里的判断逻辑,比如匹配'54016'的条件 return posting.targetId === '54016'; })) ); // 直接从过滤后的Observable中提取结果数量 this.resultsNumber$ = this.filteredPostings$.pipe( map(postings => postings.length) ); } }
然后在模板里直接使用这两个Observable:
<div class="postings-list-results-number"> {{resultsNumber$ | async}} results </div> <div class="postings-list-element" *ngFor="let posting of filteredPostings$ | async"> <div class="postings-list-element-title"> {{posting.name}} </div> </div>
方案2:用ng-container+*ngIf as捕获过滤结果
如果不想改动组件类,只想在模板层面解决,可以用这个技巧:
<ng-container *ngIf="(postingsIterableContent | async | postingsFilter:'54016') as filteredPostings"> <div class="postings-list-results-number"> {{filteredPostings.length}} results </div> <div class="postings-list-element" *ngFor="let posting of filteredPostings"> <div class="postings-list-element-title"> {{posting.name}} </div> </div> </ng-container>
这个方法的核心是利用*ngIf的as语法,把经过async和postingsFilter处理后的结果赋值给filteredPostings变量,这个变量在ng-container的整个作用域内都能访问——所以你可以在*ngFor外面直接用filteredPostings.length获取数量,而且完全不会出现重复显示的问题,因为结果数量的div只渲染一次。
为什么你之前的尝试没成功?
你说的在外部作用域声明变量、在*ngFor内部赋值的方式,Angular的模板作用域规则不允许跨作用域这么操作;而用函数设置属性的话,会因为变更检测频繁触发函数导致性能问题,还不一定能及时拿到正确值。上面的两个方案都是利用Angular的原生语法或RxJS特性,完美避开了这些坑。
内容的提问来源于stack exchange,提问作者Alexandros Rasidakis
相关产品推荐
相关产品推荐

