发表在

角训练

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,它接受两个可观察对象,并创建一个新的可观察对象,返回每个流发出的最新值:

用一个示例演示了combineLatest的行为,该示例附加了来自两个输入可观察对象的值

使用combinlatest,我们有了一种创建新数据流的方法。该数据将是一个元组,包含来自两个输入可观察对象的数据。下面是我将要使用的combinlatest方法的简化签名:

combineLatest(o1群:可见<T1>, o2:可观察值<T2>):可观察到的<(T1, T2)>;

下一步是对结果流应用转换,使其成为筛选数据的可观察对象。我们要用地图操作符来实现这一点,因为它所做的是获取一个可观察流,并将其转换为定制的数据流:

用输入值乘以10的示例说明map的行为

使用这两个操作符,我们现在可以开始过滤数据了:

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接受一个可观察对象,并为该流设置一个起始值

我们只需要从一个空过滤器开始,这意味着一个空字符串,所以我们将使用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的帮助吗?我们约个时间谈谈吧

如果你喜欢这篇文章,请鼓掌或分享。你的帮助我永远感激。

使用Medium应用程序

一个写着“在应用商店下载”的按钮,如果点击它将引导你进入iOS应用商店"class=
一个写着“开始吧,谷歌Play”的按钮,如果点击它,就会引导你进入谷歌Play商店"class=
Baidu
map