我使用的是 Angular 5 和 Material 2。
在 ts 文件中,我有这个属性:
filteredOptions: Observable<any[]>;
此属性将有一组值显示在自动完成字段中。
[{
id:'1', name: 'teste 1'},
{id:'2', name: 'teste 2'},
{id:'3', name: 'teste 3'
}]
这个值数组来自数据库,将在用户输入内容后显示。
html文件:
## <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>
ts 文件示例:
this.filteredOptions = Observable<any[]>;
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith({}),
map(getArrayOfValue(val))
);
}
// it is going to call an api to get the array of values to be shown in the field
getArrayOfValue(val): Observable<any[]> {
const url = this.ROOT_URL + 'veiculo/' + val;
return this.http.get<any[]>(url);
}
这段代码给我一个错误
ERROR in src/app/oficina/cadastro/veiculo/veiculo.component.ts(55,5): error TS2322: Type 'Observable>' is not assignable to type 'Observable'. Type 'Observable' is not assignable to type 'any[]'. Property 'includes' is missing in type 'Observable'
最佳答案
我发现了一些问题,例如您应该 map(val => this.getArrayOfValue(val))
。但我也建议进行一些额外的更改。考虑添加 debounceTime
、distinctUntilChanged
和 switchMap
。设置您选择的去抖动时间。这并不是要完全重载 api。以及 switchMap 可用于使请求切换到用户键入的最后一个值。您还应该考虑为您的 api 请求使用服务,这通常是我们处理事情的方式。所以我建议将 http-request 移动到服务并从组件调用它。
TS:
// inject your created service which makes the http-request
constructor(private service: Service) {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
debounceTime(400),
distinctUntilChanged(),
switchMap(val => {
return this.filter(val || '')
})
);
}
// filter and return the values
filter(val: string): Observable<any[]> {
// call the service which makes the http-request
return this.service.getData()
.pipe(
map(response => response.filter(option => {
return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
}))
)
}
}
然后服务会调用 http 请求。如果您不重载 API,我们可以在第一次获取后将数据存储在一个变量中,然后返回该变量的一个可观察对象,但这只是可选的。
opts = [];
getData() {
return this.opts.length ?
of(this.opts) :
this.http.get<any>('https://jsonplaceholder.typicode.com/users').pipe(tap(data => this.opts = data))
}
您似乎还使用 value
作为模板中的选项。如果要捕获整个对象,请使用 [value]
。
这是一个 DEMO 供你玩:)
关于angular 5 material 2 - 自动完成从外部api获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47637422/