拒绝输入到http服务电话

时间:2017-06-05 07:20:01

标签: html angular typescript

我目前正在做的是将输入双向绑定设置为appRequestParams.appName,并且在每个keyup事件中,将调用fetchApps()方法。

我试图去除输入,以便它不会立即触发每个键盘上的后端http请求。

我已经了解了如何去做这件事,以及我在这里发表的事情。

HTML

<input #searchBox id="search" mdInput placeholder="Search by list of apps" (keyup)="search(searchBox.value)" />

打字稿

private searchTerms = new Subject<string>();

search(value: string): void {
       this.searchTerms.next(value);
   }


fetchApps() {
       this.appService.query({
           appName: this.appRequestParams.appName ? this.appRequestParams.appName : null,
       }).subscribe(
           (res: ResponseWrapper) => this.onSuccess(res.json, res.headers),
           (res: ResponseWrapper) => this.onError(res.json)
       );
   }


ngOnInit() {
       this.searchTerms
       .debounceTime(300)
       .distinctUntilChanged()
       .switchMap((value: string) => {
           this.appRequestParams.appName = value;
           this.fetchApps();
       });
   }

.switchMap()

行的错误
Argument of type '(value: string) => void' is not assignable to parameter of type '(value: string, index: number) => ObservableInput<{}>'.
  Type 'void' is not assignable to type 'ObservableInput<{}>'.

2 个答案:

答案 0 :(得分:4)

你的代码的debounce相关部分没问题。问题是你不能在没有返回另一个observable的情况下调用switchMap。

SwitchMap基本上将Observable的最后一个发射值转换为另一个Observable,从而提供了即时自动取消http请求的能力。

尝试以下方法:

private searchTerms = new Subject<string>();

search(value: string): void {
       this.searchTerms.next(value);
   }


fetchApps() {
       this.appService.query({
           appName: this.appRequestParams.appName ? this.appRequestParams.appName : null,
       });
   }


ngOnInit() {
       this.searchTerms
       .debounceTime(300)
       .distinctUntilChanged()
       .switchMap((value: string) => {
           this.appRequestParams.appName = value;
           return this.fetchApps();
       }).subscribe(
           (res: ResponseWrapper) => this.onSuccess(res.json, res.headers),
           (res: ResponseWrapper) => this.onError(res.json)
       );
   }

典型示例与ActivatedRoute中的路径参数相关联。请考虑以下事项:

  @Injectable()
  export class FooService{
    ..
    getFooById(id:string): Observable<FooInterface>{
        return this.http.get('endpoint/${id}')
         .map(res=>res.json())
         .catch(_throw(error));
    }
  }

现在我们导航到root / foo / 10980312,其中最后一部分在路由中定义为:id

@Component({...})
class FooPreviewComponent{
  data: FooInterface;
  constructor(
    private _route: ActivatedRoute, 
    private _service: FooService) {
     this._route.params
        .switchMap(params=>
          this._service.getFooById(params.id))//switchMap return type is Observable<FooInterface> because of the definition of getFooById
        .subscribe(fooElement => this.data); //intellisense will detect the type of fooElement as FooInterface because of the return type of switchmap
  }
}

在处理http的时间内,如果我们现在导航到root / foo / 1312313,则先前的请求将自动取消。

switchMap还有其他应用程序,但它需要对内部/外部可观察对象的某些内部有所了解。

您的解决方案效率低下,因为您正在订阅去抖动的输入值和由它们触发的http响应,但是当您真的只想订阅http响应时,您对第一个没有做任何事情。因此,您可以通过正确的方式使用switchMap来保存其中一个订阅。

答案 1 :(得分:-1)

我最终使用它并且它完美无缺。

   this.searchTerms
   .debounceTime(300)
   .distinctUntilChanged()
   .switchMap(
    (term) => {
        console.log('Term:' + term);
        this.appRequestParams.appName = term;
        this.fetchApps();
        return term;
    })
    .subscribe();
}