在我看来,这个用于执行插入到输入标签中的术语的动态搜索的 Angular 管道是如何工作的?
Posted
技术标签:
【中文标题】在我看来,这个用于执行插入到输入标签中的术语的动态搜索的 Angular 管道是如何工作的?【英文标题】:How is it working this Angular pipe used to perform a dynamic search of terms inserted into an input tag in my view? 【发布时间】:2019-04-11 21:28:44 【问题描述】:我是 Angular 的新手,我正在关注这个官方 Angular 教程:https://angular.io/tutorial/toh-pt6
我对它的工作原理有些怀疑,这是我对 HeroSearchComponent 类的注释代码:
import Component, OnInit from '@angular/core';
import Observable, Subject from 'rxjs';
import
debounceTime, distinctUntilChanged, switchMap
from 'rxjs/operators';
import Hero from '../hero';
import HeroService from '../hero.service';
@Component(
selector: 'app-hero-search',
templateUrl: './hero-search.component.html',
styleUrls: [ './hero-search.component.css' ]
)
export class HeroSearchComponent implements OnInit
// It is an Observable emitting an array of Hero objects:
heroes$: Observable<Hero[]>;
/**
* The searchTerms property is declared as an RxJS Subject.
* A Subject is both a source of observable values and an Observable itself.
* You can subscribe to a Subject as you would any Observable.
* You can also push values into that Observable by calling its next(value) method as the search() method does.
*/
private searchTerms = new Subject<string>();
constructor(private heroService: HeroService)
/**
* Push a search term into the observable stream.
* Every time the user types in the textbox, the binding calls search() with the textbox value, a "search term".
* The searchTerms becomes an Observable emitting a steady stream of search terms.
*/
search(term: string): void
this.searchTerms.next(term);
ngOnInit(): void
this.heroes$ = this.searchTerms.pipe(
// wait 300ms after each keystroke before considering the term
debounceTime(300),
// ignore new term if same as previous term
distinctUntilChanged(),
// switch to new search observable each time the term changes
switchMap((term: string) => this.heroService.searchHeroes(term)),
);
该类用于从hero-search.component.html中搜索英雄,包含:
<div id="search-component">
<h4>Hero Search</h4>
<!--
As the user types in the search box, a keyup event binding calls
the component's search() method with the new search box value
-->
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<ul class="search-result">
<!--
The *ngFor iterates over a list called heroes$, not heroes.
The $ is a convention that indicates heroes$ is an Observable, not an array.
The *ngFor can't do anything with an Observable.
But there's also a pipe character (|) followed by async, which identifies Angular's AsyncPipe.
The AsyncPipe subscribes to an Observable automatically so you
won't have to do so in the component class.
-->
<li *ngFor="let hero of heroes$ | async" >
<a routerLink="/detail/hero.id">
hero.name
</a>
</li>
</ul>
</div>
这是我的解释,我绝对不确定它是否正确。
HeroSearchComponent 的 heroes$ 字段不是数组,而是发出数组的 Observable。这是因为我们生活在一个异步的世界中,所以我们必须等待服务器提供响应。
在视图中我不能直接迭代一个数组,但我必须等待我收到响应(当前面的 Observable 发出 Hero 的数组时),这是使用 asyncornous 在此事件上注册的管道:
<li *ngFor="let hero of heroes$ | async" >
这应该是正确的......
然后进入我的视图:
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
当用户在输入标签中插入一个新字符时,它被称为组件 search() 方法,传递插入到输入标签中的值(“a”、“ab”、“abc” 、“ab”等)。
这是 search() 方法:
search(term: string): void
this.searchTerms.next(term);
查看它并不是直接执行调用后端服务的搜索,而是将接收到的新词推送到 searchTerms。
这个searchTerms 对象是一个Subject。据我了解,Subject 是一个可以发出事件(作为 Observable**)同时可以接收事件流的对象(在这种情况下,每次都是术语流)用户在视图搜索输入中插入一个新字符)。
但是...如何以及在何处执行调用以获取与插入术语匹配的英雄列表?
我的想法是这样的:它不是直接在这个方法中做的,而是有一种预先设定的行为。当这个类被 ngOnInit() 方法实例化时,这是完成的:
ngOnInit(): void
this.heroes$ = this.searchTerms.pipe(
// wait 300ms after each keystroke before considering the term
debounceTime(300),
// ignore new term if same as previous term
distinctUntilChanged(),
// switch to new search observable each time the term changes
switchMap((term: string) => this.heroService.searchHeroes(term)),
);
这基本上是这样说的:调用 heroService.searchHeroes(term) 方法(在我的后端执行搜索的方法)每次传递 term searchTerms 接收\发出事件(即要搜索的最后一个词)。理论上,该管道设置为不是针对每个插入的字符而是每 300 毫秒执行一次,以避免执行太多调用)。
我不确定这种机制以及该管道的工作原理。
正确完整的解释是什么?
【问题讨论】:
到目前为止,您的所有解释都是正确的。提到的管道 (| async
) 订阅给定的 observable 并从 observable 返回给定的值。另一种可能性(或者更好的是异步管道在后台执行的操作)是调用 observable 的 subscribe 方法。两种方法之间的差异可以是read here。如果您需要有关订阅本身的更多信息take a look here
【参考方案1】:
What is pipe() function in Angular 2?
Angular 中有管道概念,RxJS 中有管道()函数
1) Angular 中的管道:管道将数据作为输入并将其转换为所需的输出 https://angular.io/guide/pipes
2) RxJS 中的 pipe() 函数:您可以使用管道将运算符链接在一起。管道让您可以将多个函数组合成一个函数。
pipe() 函数将要组合的函数作为其参数,并返回一个新函数,该函数在执行时会按顺序运行组合函数。 https://angular.io/guide/rx-library(在这个网址搜索管道,可以找到相同的)
【讨论】:
以上是关于在我看来,这个用于执行插入到输入标签中的术语的动态搜索的 Angular 管道是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章