Я очень новичок в Angualar, и я следую этому официальному учебнику по 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>
Вот мое толкование, я абсолютно не уверен, правильно это или нет.
Поле heroes $ HeroSearchComponent не является массивом, но Observable испускает массив. Это потому, что мы живем в асинхронном мире, поэтому нам приходится ждать ответа от сервера.
В представлении я не могу напрямую выполнять итерации для массива, но мне приходится ждать, пока я получу ответ (когда предыдущая наблюдаемая испускает массив Hero ), это делается с помощью асинхронный канал для регистрации на это событие:
<li *ngFor="let hero of heroes$ | async" >
Это должно быть правильно ...
Тогда в представлении у меня есть:
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
Когда пользователь вставляет новый символ во входной тег, он называется компонентом search () метод, передающий значение, вставленное во входной тег («a», «ab», «abc», "ab" и т. д.).
Это метод поиска () :
search(term: string): void {
this.searchTerms.next(term);
}
Глядя на это, вы напрямую не выполняете поиск, вызывающий внутреннюю службу, но толкаете полученный новый термин в searchTerms .
Этот searchTerms объект является Subject . Из того, что я понял, Субъект является объектом, который может генерировать событие (как наблюдаемое **) и в то же время может принимать поток четных чисел (в данном случае поток терминов каждый раз, когда пользователь вставляет новый символ в вид поиска ввода).
Но ... как и где выполняется вызов для получения списка героев, совпадающего с введенным термином?
Моя идея заключается в следующем: это напрямую не делается в этом методе, но есть что-то вроде предустановленного поведения. Это делается, когда этот класс создается методом 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 мс, чтобы избежать большого количества вызовов).
Я не уверен насчет этого механизма и того, как именно работает эта труба.
Что такое правильная и полная интерпретация?