实现异步预输入搜索的正确方法是什么?
What is the proper way to implement async typeahead search?
在我的 Angular 应用程序中,有一个 "Listings" 的页面。由于有数百个列表,结果一次只能加载 20 个,当用户滚动到底部并单击 更多.
时会加载更多列表
我想在列表上方放置一个搜索框,它可以将更具体的搜索词发送到服务器,仅发送给 return 个匹配的列表。
例如,当用户在搜索框中输入 "myterm" 时,Angular 应将 GET
发送到 https://myapp.com/listings/?search=myterm
并仅在“列表”页面。
我不确定在 Angular 2+ 中执行此操作的正确方法是什么。在 AngularJS 中,每次按下 Search 时,我都会简单地触发一个新请求 returning 一个 promise,但我怀疑 Angular2+ 有一个不同的方法。我似乎找不到任何关于它的文献。
到目前为止,我刚刚在使用空搜索参数调用服务的组件中进行了初始函数调用(又名,获取所有内容)
ngOnInit() {
this.listings = this.listingService.getListings('');
}
我建议使用 ReactiveFormsModule,因为它很容易解决这个问题。
首先,让我们定义我们的 FormGroup,它将包含一个表单控件。
form: FormGroup;
constructor(formBuilder: FormBuilder){
this.form = formBuilder.group({
search: ''
});
}
现在我们已经定义了我们的简单表单,我们感兴趣的是在用户键入时发送请求,所以基本上只要我们的表单控件的值发生变化。我们可以像这样订阅 valueChanges
Observable:
ngOnInit(){
this.form.get('search').valueChanges
.subscribe(value => this.listingService.getListings(value)));
}
这显然可行,但问题是我们不想为用户键入的每个字符发送请求。我们想等到他完成。我们可以使用 debounceTime
运算符来解决这个问题:
this.form.get('search').valueChanges
.debounceTime(1000)
.subscribe(value => this.listingService.getListings(value)));
我们还使用 switchMap
运算符来避免必须进行订阅链(因为 getListings
也是 returns 一个可观察的)。我们需要做的最后一件事是添加过滤器,因为我们不想发送带有空字符串的请求,假设用户删除了所有键入的内容。我们为此得到了 filter
运算符:
this.form.get('search').valueChanges
.filter(value => value)
.debounceTime(1000)
.switchMap(value => this.listingService.getListings(value))
.subscribe(listings => this.listings = listings);
模板应与此类似:
<form [formGroup]="form">
<input type="text" formControlName="search">
</form>
在我的 Angular 应用程序中,有一个 "Listings" 的页面。由于有数百个列表,结果一次只能加载 20 个,当用户滚动到底部并单击 更多.
时会加载更多列表我想在列表上方放置一个搜索框,它可以将更具体的搜索词发送到服务器,仅发送给 return 个匹配的列表。
例如,当用户在搜索框中输入 "myterm" 时,Angular 应将 GET
发送到 https://myapp.com/listings/?search=myterm
并仅在“列表”页面。
我不确定在 Angular 2+ 中执行此操作的正确方法是什么。在 AngularJS 中,每次按下 Search 时,我都会简单地触发一个新请求 returning 一个 promise,但我怀疑 Angular2+ 有一个不同的方法。我似乎找不到任何关于它的文献。
到目前为止,我刚刚在使用空搜索参数调用服务的组件中进行了初始函数调用(又名,获取所有内容)
ngOnInit() {
this.listings = this.listingService.getListings('');
}
我建议使用 ReactiveFormsModule,因为它很容易解决这个问题。
首先,让我们定义我们的 FormGroup,它将包含一个表单控件。
form: FormGroup;
constructor(formBuilder: FormBuilder){
this.form = formBuilder.group({
search: ''
});
}
现在我们已经定义了我们的简单表单,我们感兴趣的是在用户键入时发送请求,所以基本上只要我们的表单控件的值发生变化。我们可以像这样订阅 valueChanges
Observable:
ngOnInit(){
this.form.get('search').valueChanges
.subscribe(value => this.listingService.getListings(value)));
}
这显然可行,但问题是我们不想为用户键入的每个字符发送请求。我们想等到他完成。我们可以使用 debounceTime
运算符来解决这个问题:
this.form.get('search').valueChanges
.debounceTime(1000)
.subscribe(value => this.listingService.getListings(value)));
我们还使用 switchMap
运算符来避免必须进行订阅链(因为 getListings
也是 returns 一个可观察的)。我们需要做的最后一件事是添加过滤器,因为我们不想发送带有空字符串的请求,假设用户删除了所有键入的内容。我们为此得到了 filter
运算符:
this.form.get('search').valueChanges
.filter(value => value)
.debounceTime(1000)
.switchMap(value => this.listingService.getListings(value))
.subscribe(listings => this.listings = listings);
模板应与此类似:
<form [formGroup]="form">
<input type="text" formControlName="search">
</form>