RxJs和Angular表单的动态过滤教程
在本教程中,我们将学习如何使用RxJs操作符和一些Angular Reactive表单特性来实现数据过滤器。
我们想要实现的相对简单:我们在屏幕上有一个状态列表,当用户在文本输入中键入一些字母时,我们想要过滤掉这个列表,如上所示。
方法加载示例所需的数据HttpClient从服务器获取状态列表。当然,这只是一个例子可观测的或者静态数据也可以:
州美元:可观测状态[]> <;构造函数(私人http: HttpClient) {
这.州美元=http. get <国家[]> (“http://localhost: 8000 /州的);
}
然后,当用户在文本输入中输入新字母时,我们希望得到通知。为了做到这一点,我们将使用FormControl来自@angular/forms模块。
我们需要一个FormControl的原因是这样的对象暴露了一个valueChanges我们可以订阅的Observable。输入值中的每个更改都会发布到该订阅:
州美元:可观测状态[]> <;
过滤器: FormControl;
过滤器美元:可观察到的<字符串>;构造函数(私人http: HttpClient) {
这.州美元=http. get <国家[]> (“http://localhost: 8000 /州的);
这.过滤器=新FormControl (”);
这.过滤器美元=这.过滤器.valueChanges;
}
然后可以将FormControl绑定到组件模板中的文本输入,如下所示:
<input type="text" [formControl]="filter"占位符="filter states…">
此时,我们有两个不同的可观察数据流:一个为我们提供来自服务器的数据,另一个为我们提供来自输入字段的过滤器信息。
我们的下一步是将这两个流合并为一个流,这样我们就得到了一个统一的流,它只发布过滤后的数据。
这就是RxJs操作符将帮助我们的地方。在我们的例子中,我们将使用combineLatest,它接受两个可观察对象,并创建一个新的可观察对象,返回每个流发出的最新值:
使用combinlatest,我们有了一种创建新数据流的方法。该数据将是一个元组,包含来自两个输入可观察对象的数据。下面是我将要使用的combinlatest方法的简化签名:
combineLatest(o1群:可见<T1>, o2:可观察值<T2>):可观察到的<(T1, T2)>;
下一步是对结果流应用转换,使其成为筛选数据的可观察对象。我们要用地图操作符来实现这一点,因为它所做的是获取一个可观察流,并将其转换为定制的数据流:
使用这两个操作符,我们现在可以开始过滤数据了:
combineLatest(这.州美元,这.过滤器美元) .pipe (
地图(([states, filterString]) =>//)
);
这将我们引向下面的代码,使用数组过滤器属性的数据filterString.注意,我们使用.toLowerCase ()为了进行比较,我们使搜索不区分大小写:
combineLatest(这.州美元,这.过滤器美元) .pipe (
地图(([states, filterString]) =>
州。过滤器(状态=>状态.的名字.toLowerCase().indexOf(filterString.toLowerCase()) !== -1))
);
下面是到目前为止我们组件代码的全貌:
州美元:可观测状态[]> <;
filteredStates美元:可观测状态[]> <;
过滤器: FormControl;
过滤器美元:可观察到的<字符串>;构造函数(私人http: HttpClient) {
这.州美元=http. get <国家[]> (“http://localhost: 8000 /州的);
这.过滤器=新FormControl (”);
这.过滤器美元=这.过滤器.valueChanges;
这.filteredStates美元=combineLatest(这.州美元,这.过滤器美元) .pipe (
地图(([states, filterString]) =>状态。过滤器(状态=>状态。的名字.toLowerCase().indexOf(filterString.toLowerCase()) !== -1))
);
}
当然,这里是完整的HTML模板,呈现过滤文本输入和结果过滤状态列表:
<input type="text" [formControl]="filter"占位符="filter states…"><ul>
<李* ngFor= "让状态的filteredStates美元|异步"> {{状态.的名字}} < /李>
ul>
这是正确的工作,但有一个警告:我们必须输入至少一个字符才能看到发生的事情。这是因为combineLatest从两个可观察对象中获取最新值,因此,除非我们输入至少一个过滤字符,否则它不会执行任何操作。
这可能是一种可取的行为,但假设在我们的例子中,我们希望在输入任何筛选器之前在屏幕上看到完整的状态列表。
在这种情况下,我们要做的就是过滤器美元Observable发出一个初始值。你猜怎么着:这也有一个运算符!
我们只需要从一个空过滤器开始,这意味着一个空字符串,所以我们将使用startWith ("):
这.过滤器美元=这.过滤器.valueChanges.pipe (startWith(”));
就是这样!现在我们可以用我们期望的行为来过滤我们的数据,多亏了RxJS操作符,所有这些都只需要六行代码:
这.州美元=http. get <国家[]> (“http://localhost: 8000 /州的);
这.过滤器=新FormControl (”);
这.过滤器美元=这.过滤器.valueChanges.pipe (startWith(”));
这.filteredStates美元=combineLatest(这.州美元,这.过滤器美元) .pipe (
地图(([states, filterString]) =>状态。filter(state => state. tolowercase()。的名字.indexOf(filterString.toLowerCase()) !== -1))
);
在本教程中,我们了解了如何组合三个不同的操作符(combineLatest、map和startWith),以用户输入作为过滤标准来实现对数据集的响应式过滤。
本教程的完整代码可以在这里找到(稍微改变一下,使用本地数据,所以你不需要服务器来运行代码):
我叫betway必威滚球.我是谷歌的Angular开发专家,也是在角训练在那里我帮助开发团队学习并熟练使用Angular。
需要Angular的帮助吗?我们约个时间谈谈吧.
如果你喜欢这篇文章,请鼓掌或分享。你的帮助我永远感激。