在 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 是一个可观察对象。
使用此代码,每次更新字段时,都应刷新合作伙伴列表并应用去抖动。 (我没有测试过代码,您可能需要根据自己的用例进行调整。)
我有一个方法,每次输入文本发生变化时都会调用该方法。 (基本上就是搜索)
我想延迟 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 是一个可观察对象。
使用此代码,每次更新字段时,都应刷新合作伙伴列表并应用去抖动。 (我没有测试过代码,您可能需要根据自己的用例进行调整。)