我有一个方法,每当某些输入文本发生变化时都会调用它。 (基本上是搜索) 我想延迟发布/获取请求,因此如果用户快速输入,则只会向服务器发送一个请求。
我在想这样的事情:
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请求。
答案 0 :(得分:2)
根据我的评论。由于您使用的是Kendo,因此无法直接使用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);
}
}
NB。此代码假定this.partnersService.list()
返回一个observable。
使用此代码,每次更新字段时,都应刷新合作伙伴列表并应用去抖动。 (我还没有对代码进行测试,您可能需要根据自己的使用情况进行调整。)
答案 1 :(得分:0)
我的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);
}
答案 2 :(得分:0)
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事件值是搜索词,并且当700ms过去且输入不同时,将首先调用(搜索)
<my-user-search (search)="handleSearch($event)"></my-user-search>