有没有办法把"subscribe"的一个数组变量改成Angular?
Is there a way to "subscribe" to an array variable changes in Angular?
我正在寻找一种方法来等待用户停止交互然后发出 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
列表。
当我尝试快速连续 select 多个关键字时,问题就来了,因为这会触发对每次点击更新 suggestedKeywords
列表的请求,所以我想使用debounceTime()
防止请求在用户停止点击项目之前触发;然而,据我所知,这需要一个 Observable 来改变元素,但在我的例子中,它只是一个简单的数组。
是否有某种方式可以跟踪数组的值,以便它在发出 HTTP 请求之前等待一段时间,就像 Observable 一样?
EDIT:按照评论中的建议使用了 from()
运算符,为了实际收听更改,我是否需要定义其他方法?我在想 FormControls
.
中类似于 valueChanges()
的内容
阅读更多文档后,我倾向于 Subject
、BehaviorSubject
等;但我不确定这是否是一种正确的方法,任何人都可以提供有关如何执行此操作的示例吗?
用 Observable.of() RxJS 运算符包裹你的数组,它的行为就像 observable
我最后做的是使用 Subject
来跟踪更改,调用它的 next()
函数每次修改 suggestedKeywords
数组并将其作为可观察对象订阅.
我的组件最终看起来像这样:
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));
}
}
我正在寻找一种方法来等待用户停止交互然后发出 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
列表。
当我尝试快速连续 select 多个关键字时,问题就来了,因为这会触发对每次点击更新 suggestedKeywords
列表的请求,所以我想使用debounceTime()
防止请求在用户停止点击项目之前触发;然而,据我所知,这需要一个 Observable 来改变元素,但在我的例子中,它只是一个简单的数组。
是否有某种方式可以跟踪数组的值,以便它在发出 HTTP 请求之前等待一段时间,就像 Observable 一样?
EDIT:按照评论中的建议使用了 from()
运算符,为了实际收听更改,我是否需要定义其他方法?我在想 FormControls
.
valueChanges()
的内容
阅读更多文档后,我倾向于 Subject
、BehaviorSubject
等;但我不确定这是否是一种正确的方法,任何人都可以提供有关如何执行此操作的示例吗?
用 Observable.of() RxJS 运算符包裹你的数组,它的行为就像 observable
我最后做的是使用 Subject
来跟踪更改,调用它的 next()
函数每次修改 suggestedKeywords
数组并将其作为可观察对象订阅.
我的组件最终看起来像这样:
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));
}
}