- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在自定义 Angular Material 选择/自动完成以允许嵌套下拉列表。
在这里,我试图搜索父值或子值,但它没有被过滤掉。
此外,它应该显示为阿拉斯加(+2 个其他人)。
STACKBLITZ
<mat-form-field appearance="fill">
<mat-label>Toppings</mat-label>
<!-- <input type="text" matInput placeholder="States Group" formControlName="stateGroup" required [matAutocomplete]="autoGroup">
<mat-autocomplete #autoGroup="matAutocomplete"> -->
<input type="text" matInput placeholder="Select Users" aria-label="Select Users" matInput [matAutocomplete]="auto" [formControl]="states">
<mat-autocomplete #auto="matAutocomplete">
<!-- <mat-select [formControl]="states" multiple> -->
<mat-select-trigger>
{{states.value ? states.value[0] : ''}}
<span *ngIf="states.value?.length > 1" class="example-additional-selection">
(+{{states.value.length - 1}} {{states.value?.length === 2 ? 'other' : 'others'}})
</span>
</mat-select-trigger>
<mat-optgroup *ngFor="let group of stateList">
<div>
<mat-checkbox [checked]="group.selected" (change)="toggleParent($event, group)"
(click)="$event.stopPropagation()">
{{group.letter}}
</mat-checkbox>
<button mat-button (click)="expandDocumentTypes(group)">
<mat-icon>keyboard_arrow_down</mat-icon>
</button>
</div>
<mat-option *ngFor="let name of group.names" [value]="name"
[ngClass]="isExpandCategory[group.letter] ? 'list-show' : 'list-hide'">
<mat-checkbox [checked]="group.checked" (change)="toggleSelection($event, name, group)"
(click)="$event.stopPropagation()">
{{name.type}}
</mat-checkbox>
</mat-option>
</mat-optgroup>
<!-- </mat-select> -->
</mat-autocomplete>
<!-- </mat-autocomplete> -->
</mat-form-field>
export class SelectCustomTriggerExample {
constructor(private _formBuilder: FormBuilder){}
// stateForm: FormGroup = this._formBuilder.group({
// stateGroup: '',
// });
// toppings = new FormControl();
isExpandCategory: boolean[] = [];
toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
stateRecord:any = [];
states = new FormControl();
expandDocumentTypes(group: any) {
console.log("expanding dropdown", group);
this.isExpandCategory[group.letter] = !this.isExpandCategory[group.letter];
// expand only selected parent dropdown category with that childs
}
toggleSelection(event:any, name: any, group: any) {
debugger;
console.log("toggleSelection", name, event.checked, group);
if(event.checked) {
console.log("stastateRecordtelist", this.stateRecord);
this.stateRecord.push(name.type);
this.states.setValue(this.stateRecord);
console.log("toggleselection ", this.states.value);
}
else {
this.stateRecord = this.stateRecord.filter((x:any) => x!== name.type);
console.log("else toggleselection", name, group, this.states.value);
this.states.setValue(this.states.value.filter((x:any) => x!== name.type));
console.log("after filter ", this.states.value);
//this.states.setValue([]);
}
}
toggleParent(event: any, group: any) {
debugger;
group.checked = event.checked;
console.log("event", event.checked, "group", group, "states value", this.states.value);
let states = this.states.value;
states = states ? states : [];
if(event.checked) {
states.push(...group.names.filter((x: any) => !states.includes(x.type)).map((x: any) => x.type))
} else {
console.log("else", states);
group.names.forEach((x: any) => {
if(states.indexOf(x.type) > -1) {
states.splice(states.indexOf(x.type), 1)
}
});
}
this.states.setValue(states);
console.log("statesvalue", this.states.value);
if(!event.checked) {
this.states.setValue(this.states.value.filter((x:any) => !x.includes(group.names)))
//this.states.setValue([]);
}
console.log("final statesvalue", this.states.value);
this.stateRecord = this.states.value;
}
stateList = [
{
"letter":"A",
"checked":false,
"names":[
{
"id":1,
"type":"Alabama"
},
{
"id":2,
"type":"Alaska"
},
{
"id":3,
"type":"Arizona"
},
{
"id":4,
"type":"Arkansas"
}
]
},
{
"letter":"C",
"checked":false,
"names":[
{
"id":8,
"type":"California"
},
{
"id":9,
"type":"Colorado"
},
{
"id":10,
"type":"Connecticut"
}
]
},
{
"letter":"D",
"checked":false,
"names":[
{
"id":18,
"type":"Delaware"
},
{
"id":19,
"type":"Denwer"
}
]
}
];
}
引用:
最佳答案
这个任务相当复杂,需要更多的说明,也许可以通过一些专用的库来解决,比如 https://www.npmjs.com/package/mat-select-autocomplete
但我喜欢您逐步推进此自定义控件并希望获得比您已经实现的更好的东西。
让我们尝试解决您在这个问题中指出的两个问题:
它应该过滤父值或子值
Angular 形 Material 使我们能够define custom filter .您可以在示例中使用类似的逻辑。只需创建一个 Observable
这是 FormControl
的听众变化:
this.stateGroupOptions$ = this.states.valueChanges.pipe(
startWith(EMPTY_STRING),
...
map(value => this._filterGroup(value))
);
...
private _filterGroup(value: any) {
if (!this.searching || !value.trim()) {
return this.stateList;
}
value = value.trim().toLowerCase();
return this.stateList
.map(group => ({
...group,
names: group.names.filter(item => item.type.toLowerCase().includes(value))
}))
.filter(
group => group.letter.toLowerCase().includes(value) || group.names.length > 0
);
}
然后在您的选项列表中使用它
<mat-optgroup *ngFor="let group of stateGroupOptions$ | async">
它应该显示为
Alaska (+2 others)
.
displayWith
input property
@Input() displayWith: ((value: any) => string) | null
Function that maps an option's control value to its display value in the trigger.
<mat-autocomplete ... [displayWith]="displayWith"
ts
displayWith(names: StateName[]) {
if (!names || !names.length) {
return "";
}
return (
names[0].type +
(names.length > 1
? ` (+${names.length - 1} ${names.length === 2 ? "other" : "others"})`
: "")
);
}
Stackblitz Example
string
(当用户开始打字时),
Array
(当您单击复选框并手动更新控件时)和
Object
(当您从下拉列表中选择选项时)。
关于javascript - 垫子自动完成不能以 Angular 正确过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63173753/
用 OpenCV(C++) 表示垫子的最佳方法是什么?目前在我的代码中,我使用 vector 的 vector 我需要使用矩阵的好处。 最佳答案 仅限于我的搜索,不幸的是,Opencv-C++ 中没有
我想将 Mat 图像的所有 channel 添加到只有一个和 channel 的 Mat 图像中。我试过这样: // sum up the channels of the image:
我是一名优秀的程序员,十分优秀!