【问题标题】:Emit http requests + debounce on Kendo field changes发出 http 请求 + 对 Kendo 字段更改进行反跳
【发布时间】:2017-02-15 12:43:14
【问题描述】:

我有一个方法,每次更改某些输入文本时都会调用该方法。 (基本上是搜索)。
我想延迟发布/获取请求,因此如果用户快速键入,则只会向服务器发送一个请求。

我在想这样的事情:

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请求。

【问题讨论】:

  • 将switchMap 用于搜索过滤器。 angular.io/docs/ts/latest/guide/…
  • 你需要重构你的代码,使debounceTime()操作符位于发出过滤器值的observable和发出HTTP请求的observable之间。类似 this.filter.valueChanges.debounceTime(400).mergeMap(filter => this. partnersService.search(term)) 的东西。见blog.thoughtram.io/angular/2016/01/06/…
  • 您可以随时将收到的来自 Kendo 的更改推送到您自己的自定义 observable。如果你想去抖动发射的值,它们必须被包裹在一个可观察对象中。
  • @AngularFrance:谢谢 - 只是一个小问题。我不能使用 form.valueChanges 因为值没有改变。 DropDown 上的事件(按下键)在内部处理,并且在您选择项目时更改表单值,而不是在搜索时。
  • form.valueChanges 仅适用于原始 Angular 字段。就像我说的,由于您使用的是 Kendo,因此您需要将从 Kendo 收到的值推送到您自己的 observable 中。请参阅下面的答案。

标签: javascript angular rxjs kendo-ui-angular2


【解决方案1】:

根据我的评论。你不能直接使用form.get('fieldName').valueChanges,因为你使用的是剑道。但是您可以将从 Kendo 收到的值推送到您自己的自定义 observable,从而复制 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() 返回一个可观察对象。

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

【讨论】:

    【解决方案2】:
    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值是搜索词,(search)会在700ms过去后首先调用,输入不一样

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

    【讨论】:

    • 只是一个小问题。我不能使用 form.valueChanges 因为值没有改变。 DropDown 上的事件(按下键)在内部处理,并且在您选择项目时更改表单值,而不是在搜索时。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2017-05-02
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      相关资源
      最近更新 更多