angular - 具有嵌套 JSON 结构的 Angular MatOptGroup 自动完成
问题描述
有一些使用 JSON 结构的 MatOptGroup 过滤示例,但它们不是嵌套的。这就是为什么我要解决这个问题。
<mat-form-field>
<mat-label>Database</mat-label>
<mat-select [formControl]="databaseControl">
<mat-option>-- None --</mat-option>
<mat-optgroup *ngFor="let group of databaseGroups" [label]="group.name" [disabled]="group.disabled">
<mat-option *ngFor="let children of group.children" [value]="children.name">
{{children.name}}
</mat-option>
</mat-optgroup>
</mat-select>
</mat-form-field>
目前它是这样工作的。结构嵌套如下:
export interface Database {
name: string;
}
export interface DatabaseGroup {
disabled?: boolean;
name: string;
children: Database[];
}
有一个没有嵌套结构的例子:https ://stackblitz.com/edit/angular-smg2xm?file=app/app.component.ts
我尝试过这样的事情,但这不起作用,因为过滤器不知道彼此的价值:
private _filterGroups(value: string): string[] {
const filterValue = value.toLowerCase();
this.options = this.databaseGroups.filter(function (database) {
database.children.filter(function (sipp) {
return sipp.name.toLowerCase().includes(filterValue);
})
});
return this.options;
}
没有嵌套结构的解决方案:
filterGroup(val: string): SpeciesGroup[] {
if (val) {
return this.speciesGroup
.map(group => ({ letter: group.letter, name: this._filter(group.name, val) }))
.filter(group => group.name.length > 0);
}
return this.speciesGroup;
}
解决方案
我解决了。
export const _filterChildren = (opt: Database[], value: string): Database[] => {
const filterValue = value.toLowerCase();
return opt.filter(item => item.name.toLowerCase().indexOf(filterValue) === 0);
};
filteredOptions: Observable<DatabaseGroup[]>;
databaseControl = new FormControl();
databaseGroups: DatabaseGroup[];
private _filterGroup(value: string): DatabaseGroup[] {
if (value) {
return this.databaseGroups
.map(group => ({ children: _filterChildren(group.children, value), name: group.name }))
.filter(group => group.children.length > 0);
}
return this.databaseGroups;
}
ngOnInit() {
this.filteredOptions = this.databaseControl.valueChanges
.pipe(
startWith(''),
map(value => this._filterGroup(value))
);
}
<mat-form-field>
<mat-label>{{'CSV.DBATTR' | translate}}</mat-label>
<input matInput placeholder="{{'CSV.CHOOSE' | translate}}" [matAutocomplete]="auto"
[formControl]="databaseControl">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option>{{'CSV.NONE' | translate}}</mat-option>
<mat-optgroup *ngFor="let group of filteredOptions | async" [label]="group.name">
<mat-option *ngFor="let children of group.children" [value]="children.name">
{{children.name}}
</mat-option>
</mat-optgroup>
</mat-autocomplete>
</mat-form-field>
您可以在问题中找到两个使用过的界面,您现在可以自动完成子项,但只能自动完成子项。如果有人知道如何自动完成父母或选择组,请随时回答。
推荐阅读
- python - Python文件指向错误的python安装
- ios - 带有 UITableViewController 的 iOS 标签栏应用
- angular - 有没有人有用于 nativescript + angular 的 RadPieChart 示例?
- java - 来自 AdminInitiateAuth 的 ID 令牌对 API 网关调用无效
- ruby-on-rails - 控制台未出现在 Rails 操作视图中
- amazon-web-services - 如何使用 AWS IAM 策略连接 EC2 和 ECR 跨区域?
- java - frontpage 从 model.addAttribute 获取对象的长类型 id 失去精度
- keras - Keras 函数(K.function)不适用于 RNN(提供的代码)
- scala - scala - 使用正则表达式替换第 2 次和第 4 次出现
- python - 请解释 [1,-1][x < 0]