Angular用ngFor渲染列表时能否无需自建Pipe实现条件过滤?
完全不需要编写完整自定义Pipe,有3种轻量实现方式满足需求
方案1:直接在ngFor迭代源位置做内联过滤
适合单条件、简单判断的场景,不需要额外代码文件,写完即时生效:
<!-- 直接把原entries替换为实时过滤后的数组源 --> <div *ngFor="let x of entries.filter(item => item.hero !== 'heroes'); let i = index" class="personal">
- 逻辑全部写在模板内,不需要单独建组件方法、不需要注册Pipe,只要entries数组发生变更,Angular的变更检测会自动重新执行过滤,完全满足实时更新的要求
- 注意:这种写法适合列表长度不大的场景,如果单次数组超过上百条,每次变更检测都重新全量遍历过滤会有轻微性能开销
方案2:列表项内部配合*ngIf做判断(大列表更优)
如果列表条目很多,不想在迭代源位置做全量遍历,可以保留原数组的迭代流程,在每个列表项的渲染节点上加判断,用ng-container包裹避免生成多余DOM节点:
<ng-container *ngFor="let x of entries; let i = index"> <!-- 直接在ngIf里写TS判断,不要加插值语法{{}} --> <div *ngIf="x.hero !== 'heroes'" class="personal"> <!-- 原列表项内容 --> </div> </ng-container>
- 不需要提前遍历整个数组做过滤,逐行判断逐行渲染,大列表下性能比内联filter更稳定
方案3:组件类写轻量getter做过滤
如果后续过滤逻辑可能变复杂,不想把所有判断堆在模板里,可以在组件类里写一个普通的getter做过滤,比写Pipe轻量很多,没有任何额外配置步骤:
// 组件类内的代码 get displayableEntries() { // 核心判断逻辑:hero属性等于'heroes'的项全部排除 return this.entries.filter(item => item.hero !== 'heroes'); }
模板里直接绑定这个getter作为迭代源即可:
<div *ngFor="let x of displayableEntries; let i = index" class="personal"></div>
写法误区说明
- 想要在ngFor行内直接实现“x.hero等于'heroes'就不展示”的判断是完全可以的,不需要特殊语法支持
- 之前尝试的
*ngIf="{{x.hero}} == 'heroes'"是错误写法:Angular结构型指令的表达式本身就是直接解析组件上下文的TS代码片段,不能在指令表达式里嵌套插值语法{{}},这种写法会直接触发模板解析错误。正确的判断写法是*ngIf="x.hero !== 'heroes'"。
内容的提问来源于stack exchange,提问作者Someguy
相关产品推荐
相关产品推荐

