在 Kendo 字段更改时发出 http 请求 + 反跳

Emit http requests + debounce on Kendo field changes

我有一个方法,每次输入文本发生变化时都会调用该方法。 (基本上就是搜索)
我想延迟 post/get 请求,这样如果用户快速输入,只会向服务器发送一个请求。

我在想这样的事情:

public partnerFilterChange(value)
{
    if (this.partnersSubscriptions)
        this.partnersSubscriptions.unsubscribe();

    this.partnersSubscriptions = this.partnersService.list({ filter: value })
        .debounceTime(5000)
        .subscribe(partners =>
        {
            delete this.partnersSubscriptions;
            this.partners = partners;
        });
}

但它不起作用。

Http 请求立即执行,而不是在 5 秒后执行。我也尝试 delay 而不是 debounceTime.

已编辑:

我正在使用 kendo drop down list component and its change event,所以我无法控制函数调用,只能订阅 http 请求。

我在我的 Angular 2 应用程序中遇到了类似的问题,我将粘贴我的解决方案:

subscribeToSearchQueryChanges(){
        const sub = Observable.fromEvent(this.panelSuggestionBox.nativeElement, 'keyup')
            .debounceTime(300)
            .filter((kbE: KeyboardEvent) => {
                return !(kbE['code'] === 'Space' || kbE.key === 'ArrowDown' || kbE.key === 'ArrowUp' || kbE.key === 'Enter' || kbE.key === 'Tab' || kbE.key === 'Shift')
            })
            .map(() => _.trim(this.panelSuggestionBox.nativeElement.value) )
            .filter((term: string) => term.length > 2 )
            .switchMap((term: string) => this.suggestionService.getSuggestions(this.suggestionTypes, term))
            .subscribe((suggestions: Suggestion[]) => {
                this.suggestionsData = this.suggestionService.groupSuggestions(suggestions);
                this.toggleSuggestionList();
            }, err => {
                console.error('suggestions failed', err);
                this.removeSubscription(sub);
                this.subscribeToSearchQueryChanges();
            });

        this.addSubscription(sub);
    }
import { Component, Output, HostListener, ChangeDetectionStrategy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'my-user-search',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <form role="search" class="navbar-form-custom form-inline" [formGroup]="searchForm">
      <div class="form-group">
        <label for="user-search">Search</label>
        <input
          id="user-search"
          class="form-control"
          name="input"
          type="text"
          placeholder="Search Co-worker"
          formControlName="search"
        />
      </div>
    </form>
  `
})
export class UserSearchComponent {

  searchForm = new FormGroup({
    search: new FormControl('')
  });

  @Output() search: Observable<string> = this.searchForm.valueChanges
    .map(form => form.search)
    .debounceTime(700)
    .distinctUntilChanged();

  @HostListener('window:keyup', ['$event'])
  cancelSearch(event) {
    if (event.code === 'Escape') {
      this.searchForm.reset();
      // this.searchControl.setValue('', {emitEvent: true});
    }
  }

}

用法

其中 $event 值是搜索词,当 700 毫秒过去并且输入不相同时,将首先调用 (search)

<my-user-search (search)="handleSearch($event)"></my-user-search>

根据我的评论。您不能直接使用 form.get('fieldName').valueChanges,因为您正在使用 Kendo。但是您可以将从 Kendo 收到的值推送到您自己的自定义可观察对象,从而复制 valueChanges:

的行为
class AppComponent {
  // This is your own, custom observable that you'll subscribe to.
  // It will contain a stream of filter values received from Kendo.
  private _filterValues: Subject<string> = new Subject<string>();

  constructor() {
    // Start from your custom stream, debounce values, and run http query
    this._filterValues.asObservable()
      .debounceTime(400)
      .mergeMap(value => this.partnersService.list({ filter: value }))
      .subscribe(partners => this.partners = partners);
  }

  // This method is called by Kendo every time the field value changes.
  handleFilter(value) {
    // Push the value in the custom stream.
    this._filterValues.next(value);
  }
}

注意。此代码假定 this.partnersService.list() returns 是一个可观察对象。

使用此代码,每次更新字段时,都应刷新合作伙伴列表并应用去抖动。 (我没有测试过代码,您可能需要根据自己的用例进行调整。)