在发出新请求时,如何防止更新的搜索栏取消先前的请求? [英] How do I prevent an updating search bar to cancel a previous request when a new one is made?

查看:80
本文介绍了在发出新请求时,如何防止更新的搜索栏取消先前的请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a search bar that does a search for events based on an id. As more numbers are typed in the search bar it is continuously updating to search for events based on the partial id typed. So when I stop typing, my newest results are getting updated by the previous requests.

示例.我通过键入12345进行搜索.

Example. I search by typing 12345.

显示的结果为12345

Results are shown for 12345

然后通过1234的结果对其进行更新.

Then it gets updated by results of 1234.

然后它会根据123的结果进行更新.

Then it gets updated by results of 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
  }
}

'''

推荐答案

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

I think you should get what you're looking for if you use the standard RxJS operators used for these specific scenarios, like:

  1. map-将keyup事件转换为可用于搜索的文本.
  2. debounceTime-等待x ms之后再执行操作.因此,如果用户在这x毫秒内更改了任何内容,则不会考虑.
  3. distinctUntilChanged-检查该值是否在x毫秒内实际上已更改.
  4. tap-在实际进行API调用之前设置加载状态.
  5. switchMap-将Observable的上下文切换为http.get调用的结果.
  6. catchError-为了处理API带来的错误,以防万一.
  1. map - To transform the keyup event into a text that could be used for the search.
  2. debounceTime - To wait until x ms before doing something. So if the user changes anything within those x ms, it won't be accounted for.
  3. distinctUntilChanged - To check if the value has actually changed within x ms.
  4. tap - To set the loading state before actually making an API call.
  5. switchMap - To switch the context of the Observable to the result of the http.get call.
  6. catchError - To handle the errors coming in from API, just in case there are any.


尝试一下:


Give this a try:

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)
    );
  }
}


这是一个

Here's a Working Sample StackBlitz for your ref.

这篇关于在发出新请求时,如何防止更新的搜索栏取消先前的请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆