我正在寻找一种等待用户停止交互然后发出HTTP请求的方法,为此,我正在寻找来自RxJs的debounceTime()
运算符,但我正在等待的目标是我定义的数组。
这是场景:
export class KeywordSelectionComponent implements OnInit {
constructor(private proposalService: ProposalService) { }
@ViewChild(MatTable, {static: true}) kwTable: MatTable<any>;
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
@Input() proposalId: string;
keywordInput = new FormControl(null, Validators.required);
dataSource: MatTableDataSource<Keyword>;
displayedColumns = ['action', 'keyword', 'searches', 'competition', 'cpc'];
suggestedKeywords: Keyword[] = [];
selectedKeywords: string[] = [];
fetchSuggestions(seeds?: string[]) {
const ideas = {
seeds: [],
limit: 25
};
this.proposalService.getKeywordIdeas(this.proposalId, ideas).pipe(retry(3)).subscribe(res => {
this.suggestedKeywords = res;
});
}
}
我这里不包括整个组件,但想法如下:
我在页面上呈现了一个suggestedKeywords
列表,每个列表都应调用一个addKeyword()
方法以将该关键字添加到dataSource
中,然后,我调用fetchSuggestions()
方法来获取新关键字以填充suggestedKeywords
列表。
当我尝试快速连续选择多个关键字时,就会出现问题,因为这将触发每次点击的请求来更新suggestedKeywords
列表,因此我想使用debounceTime()
来阻止请求触发,直到用户停止单击项目一会为止;但是据我所知,这需要将Observable更改为元素,但就我而言,它只是一个简单的数组。
是否有某种方式可以跟踪数组的值,以便它在更改之后等待一段时间,然后再发出HTTP请求(例如Observable)?
编辑:如注释中所建议的,使用了from()
运算符,为了实际收听更改,我是否需要定义其他方法?我在想类似于valueChanges()
中的FormControls
。
浏览更多文档,我倾向于Subject
,BehaviorSubject
等;但是我不确定这是否是正确的方法,谁能提供一个有关如何执行此操作的示例吗?
答案 0 :(得分:1)
将数组包装到Observable.of()RxJS运算符中,其行为将类似于Observable
答案 1 :(得分:0)
我最终要做的是使用Subject
跟踪更改,将其next()
函数称为evrytime,将其修改为suggestedKeywords
数组,并按照可观察的方式进行订阅。 / p>
我的组件最终看起来像这样:
export class KeywordSelectionComponent implements OnInit {
constructor(private proposalService: ProposalService) { }
keywordInput = new FormControl(null, Validators.required);
suggestedKeywords: Keyword[] = [];
selectedKeywords: string[] = [];
isLoadingResults = false;
tag$ = new Subject<string[]>();
ngOnInit() {
this.tag$.asObservable().pipe(
startWith([]),
debounceTime(500),
switchMap(seeds => this.getSuggestionsObservable(seeds))
).subscribe(keywords => {
this.suggestedKeywords = keywords;
});
}
addSuggestedKeyword(keyword: Keyword) {
const suggestedKeyword = keyword;
const existing = this.dataSource.data;
if (!existing.includes(suggestedKeyword)) {
existing.push(suggestedKeyword);
this.dataSource.data = existing;
}
this.tag$.next(this.getCurrentTableKeywords());
}
fetchKeywordSearch(keyword: string) {
this.isLoadingResults = true;
this.keywordInput.disable();
const search = {
type: 'adwords',
keyword
};
const currentData = this.dataSource.data;
this.proposalService.getKeywordSearch(this.proposalId, search).pipe(retry(3)).subscribe(res => {
currentData.push(res);
this.dataSource.data = currentData;
}, error => {},
() => {
this.isLoadingResults = false;
this.keywordInput.enable();
this.tag$.next(this.getCurrentTableKeywords());
});
}
getCurrentTableKeywords(): string[] {}
getSuggestionsObservable(seeds: string[] = []): Observable<Keyword[]> {
const ideas = {
type: 'adwords',
seeds,
limit: 25
};
return this.proposalService.getKeywordIdeas(this.proposalId, ideas).pipe(retry(3));
}
}