Методы ввода расширенного поиска в Angular: использование операторов switchMap и debounceTime

В этой статье блога мы рассмотрим передовые методы реализации ввода поиска в приложении Angular. Мы уделим особое внимание использованию операторов switchMap и debounceTime, предоставляемых RxJS, мощной библиотекой реактивного программирования, используемой в Angular.

Зачем использовать switchMap и debounceTime?
При создании поисковых данных крайне важно оптимизировать производительность и удобство работы с пользователем. Оператор switchMap позволяет нам отменять предыдущие запросы поиска при создании нового, предотвращая ненужные сетевые вызовы и гарантируя получение только последних результатов поиска. С другой стороны, оператор debounceTime помогает нам контролировать скорость отправки поисковых запросов, сокращая количество запросов и улучшая скорость реагирования пользовательского интерфейса.

Метод 1: использование switchMap и debounceTime с HttpClient
Начнем с импорта необходимых модулей и сервисов:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { debounceTime, switchMap } from 'rxjs/operators';

Далее мы реализуем функцию поиска в нашем компоненте:

@Component({
  selector: 'app-search',
  template: `
    <input type="text" [(ngModel)]="searchTerm" (input)="onSearch()">
    <ul>
      <li *ngFor="let result of searchResults$ | async">{{ result }}</li>
    </ul>
  `
})
export class SearchComponent {
  searchTerm: string;
  searchResults$: Observable<string[]>;
  constructor(private http: HttpClient) {}
  onSearch(): void {
    this.searchResults$ = this.http.get<string[]>(`/api/search?term=${this.searchTerm}`).pipe(
      debounceTime(300),
      switchMap((results: string[]) => {
        return results;
      })
    );
  }
}

В приведенном выше коде мы привязываем входные данные поиска к свойству searchTermс помощью ngModelи прослушиваем изменения входных данных с помощью события (input). При изменении условия поиска вызывается метод onSearch(). Внутри этого метода мы используем оператор debounceTimeдля задержки поискового запроса на 300 миллисекунд, гарантируя, что пользователь закончил ввод перед отправкой запроса. Затем оператор switchMapиспользуется для отмены всех предыдущих поисковых запросов и переключения на последний.

Метод 2: использование switchMap и debounceTime с реактивными формами
Если вы используете подход реактивных форм Angular, реализация будет немного отличаться. Вот пример:

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { debounceTime, switchMap } from 'rxjs/operators';
@Component({
  selector: 'app-search',
  template: `
    <input type="text" [formControl]="searchControl">
    <ul>
      <li *ngFor="let result of searchResults$ | async">{{ result }}</li>
    </ul>
  `
})
export class SearchComponent {
  searchControl = new FormControl();
  searchResults$: Observable<string[]>;
  constructor(private http: HttpClient) {}
  ngOnInit(): void {
    this.searchResults$ = this.searchControl.valueChanges.pipe(
      debounceTime(300),
      switchMap((term: string) => {
        return this.http.get<string[]>(`/api/search?term=${term}`);
      })
    );
  }
}

В этом примере мы создаем FormControlс именем searchControlи привязываем его к вводу поиска с помощью [formControl]. Мы прослушиваем изменения в значении элемента управления формы, используя наблюдаемую valueChanges. Оператор debounceTimeприменяется к изменениям значений, а оператор switchMapобрабатывает поисковые запросы аналогично тому, как в предыдущем примере.

Включив операторы switchMap и debounceTime из RxJS, вы можете создать высокопроизводительный поиск в своем приложении Angular. Оператор switchMap гарантирует, что будет обработан только последний поисковый запрос, а оператор debounceTime контролирует скорость отправки запросов, повышая скорость реагирования пользовательского интерфейса. Эти методы способствуют улучшению пользовательского опыта и оптимизации функций поиска.