Angular2中如何在ngForOf内使用Pipe过滤值?
给Angular的*ngFor添加过滤Pipe的实现方案
Hey there! 作为刚从AngularJS转过来的新手,我太懂你这种想给列表加过滤的需求了——毕竟ng-repeat那套直接绑定过滤的方式用惯了,换到Angular的*ngFor确实得适应一下。不过别担心,自定义Pipe来实现过滤其实很简单,咱们一步步来:
1. 创建自定义过滤Pipe
Angular从2.x开始就移除了内置的过滤Pipe,官方鼓励我们根据需求自定义,这样更灵活也更可控。你可以用Angular CLI快速生成,或者手动创建文件:
方式一:用CLI生成
在终端运行:
ng generate pipe filterHeroes
这会自动帮你生成filter-heroes.pipe.ts文件,并且在模块里声明好(如果是默认的AppModule的话)。
方式二:手动编写Pipe代码
如果不用CLI,自己创建filter-heroes.pipe.ts文件,内容如下:
import { Pipe, PipeTransform } from '@angular/core'; // 导入你的Hero类型定义,假设你已经有这个文件了 import { Hero } from './hero'; @Pipe({ name: 'filterHeroes' // 这个名字是你在模板里要用的Pipe名称 }) export class FilterHeroesPipe implements PipeTransform { // transform方法是Pipe的核心,接收原数组和过滤参数,返回过滤后的数组 transform(heroes: Hero[], searchTerm: string): Hero[] { // 边界处理:如果没有数组或者没有搜索词,直接返回原数组 if (!heroes || !searchTerm) { return heroes; } // 这里写你的过滤逻辑,比如按英雄名称模糊匹配,忽略大小写 return heroes.filter(hero => hero.name.toLowerCase().includes(searchTerm.toLowerCase()) ); } }
2. 在模块里声明Pipe
如果是手动创建的Pipe,一定要在对应的模块(比如AppModule)里声明它,不然模板里用不了:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; // 注意要导入FormsModule,因为后面要用ngModel双向绑定 import { FilterHeroesPipe } from './filter-heroes.pipe'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent, FilterHeroesPipe // 把Pipe添加到declarations数组里 ], imports: [ BrowserModule, FormsModule // 必须导入这个才能用[(ngModel)] ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
3. 在模板里使用Pipe过滤*ngFor列表
现在回到你的app.component.html,先加一个输入框让用户输入过滤关键词,然后在*ngFor里用上咱们的Pipe:
<!-- 双向绑定搜索关键词到组件里的searchTerm变量 --> <input type="text" [(ngModel)]="searchTerm" placeholder="输入英雄名称搜索..."> <!-- 用filterHeroes Pipe过滤heroes数组,把searchTerm作为参数传进去 --> <ul> <li *ngFor="let hero of heroes | filterHeroes: searchTerm"> {{ hero.name }} - {{ hero.power }} <!-- 这里替换成你英雄对象的属性 --> </li> </ul>
然后在app.component.ts里添加searchTerm变量:
import { Component } from '@angular/core'; import { Hero } from './hero'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { // 你已经有的heroes数组 heroes: Hero[] = [ { name: '蜘蛛侠', power: '蜘蛛感应&蛛丝发射器' }, { name: '雷神', power: '雷神之锤&风暴战斧' }, { name: '绿巨人', power: '愤怒变身&超强力量' } ]; // 新增搜索关键词变量,初始为空 searchTerm = ''; }
一些额外的小提醒
- 如果你的heroes数组是从API异步获取的(比如用HttpClient),记得结合
asyncPipe一起用,比如*ngFor="let hero of heroes$ | async | filterHeroes: searchTerm"(其中heroes$是Observable类型)。 - 默认的Pipe是纯Pipe,只有当输入的数组或者参数发生引用变化时才会重新执行过滤。如果你的数组内容变化但引用没改(比如push新元素),可以考虑把Pipe设置为非纯的(在@Pipe装饰器里加
pure: false),不过非纯Pipe会频繁执行,要注意性能哦。
内容的提问来源于stack exchange,提问作者kkom
相关产品推荐
相关产品推荐

