在发出新请求时,如何防止更新的搜索栏取消先前的请求?

时间:2019-07-19 15:12:40

标签: angular

我有一个搜索栏,可以根据ID搜索事件。随着在搜索栏中键入更多数字,它会不断更新以根据键入的部分ID搜索事件。因此,当我停止键入内容时,最新的结果将根据先前的请求进行更新。

示例。我输入12345进行搜索。

显示的结果为12345

然后通过1234的结果进行更新。

然后它被123的结果更新。

更新:

'''

export class SearchComponent implements OnInit {

  events: Events[]
  triggered = false

  constructor(private eventService: EventService) {

  }


  ngOnInit() {
    this.events = <Events[]>[]
  }

  searchForEvents(searchTerm) {
    this.eventService.getEventsByPartialId(searchTerm)
      .subscribe(data => this.events = data)
    this.triggered = true
  }
}

'''

1 个答案:

答案 0 :(得分:2)

如果您使用用于这些特定方案的标准RxJS运算符,我想您应该找到想要的东西,

  1. map-将keyup事件转换为可用于搜索的文本。
  2. debounceTime-等待x毫秒后再执行操作。因此,如果用户在这x毫秒内更改了任何内容,则不会考虑。
  3. distinctUntilChanged-检查该值是否在x毫秒内实际上已更改。
  4. tap-在实际进行API调用之前设置加载状态。
  5. switchMap-将Observable的上下文切换为http.get调用的结果。
  6. catchError-为了处理API带来的错误,以防万一。

尝试一下:

import { Component, Injectable, ViewChild, ElementRef } from '@angular/core';
import { Observable, fromEvent, of } from 'rxjs';
import { map, distinctUntilChanged, debounceTime, tap, switchMap, catchError } from 'rxjs/operators';
import { SearchService } from './search.service';


@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  model: Observable<any>;
  searching = false;
  searchFailed = false;
  searchField$: Observable<any>;
  @ViewChild('input', { static: true }) input: ElementRef;

  constructor(private _service: SearchService) { }

  ngAfterViewInit() {
    this.searchField$ = fromEvent(this.input.nativeElement, `keyup`);
    this.model = this.searchField$.pipe(
      map(event => event.target.value),
      debounceTime(300),
      distinctUntilChanged(),
      tap(() => this.searching = true),
      switchMap(term =>
        this._service.search(term).pipe(
          tap(() => this.searchFailed = false),
          catchError(() => {
            this.searchFailed = true;
            return of([]);
          }))
      ),
      tap(() => this.searching = false)
    );
  }
}

  

这是您推荐的Working Sample StackBlitz