我正在遵循Autocomplete Angular Material documentation(v5设置单独的控件和显示值),但是在加载数据时遇到了一些问题。
我遇到的问题是,直到用户开始键入后,我的代码中的filteredOptions才会填充。在用户开始输入之前,我需要显示该列表。我相信这是因为他们正在使用valueChanges,但是我不太确定如何使这段代码适合我的情况。我需要此管道和地图功能,但是我需要在用户更改Mat Autocomplete值之前而不是之后更改列表。
从文档链接中获取的代码或多或少已映射到自己的代码中
<form class="example-form">
<mat-form-field class="example-full-width">
<input type="text" placeholder="Assignee" aria-label="Assignee" matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
filteredOptions: Observable<User[]>;
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith<string | User>(''),
map(value => typeof value === 'string' ? value : value.name),
map(name => name ? this.filter(name) : this.categoryList.slice())
);
}
filter(name: string): User[] {
return this.categoryList.filter(option =>
option.name.toLowerCase().indexOf(name.toLowerCase()) === 0);
}
displayFn(user?: User): string | undefined {
return user ? user.name : undefined;
}
this.categoryList = Object.entries(data.category).map(([key, value]) => ({ key, value }));
我当时想我应该使用某种订阅方式,但是我不知道将其用于管道和地图的语法。
答案 0 :(得分:0)
我相信您要做的就是startWith
表单的值:
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(this.myControl.value as string), // typing the control's value
map(name => name ? this.filter(name) : this.categoryList.slice())
);
}
请注意,在运算符内部使用class方法有点反模式。通常,在使用Observable模式时保持事物纯净非常重要-尤其是对于更复杂的逻辑。
要解决此问题,您可能希望将categoryList
设为可观察对象,并将filter
设为纯函数(将其带到组件外部,并为其提供另一个参数,以便您可以通过在categoryList
中。
function filter(name: string, categoryList: User[]): User[] {
categoryList.filter(option =>
option.name.toLowerCase().indexOf(name.toLowerCase()) === 0);
}
然后您可以这样做:
ngOnInit() {
this.filteredOptions = combineLatest(
this.myControl.valueChanges.pipe(startWith(this.myControl.value as string)),
this.categoryList
).pipe(
map(([searchTerm, categoryList]) =>
searchTerm ? filter(searchTerm, categoryList) : [ ...categoryList ])
);
}
答案 1 :(得分:0)
简直不敢这么简单,但是这个答案帮助解决了所有问题。我要做的就是将代码移到ngOnInit之外。 how to show autocomplete options on focus
我的filteredOptions没有等待API数据通过,因为我已经将其放入ngOnInit中。将其移到api调用的订阅中后,一切运行顺利。