我需要使用 Mat-Select 指令的下拉过滤器由按钮而不是输入字段调用和显示。另外,我想隐藏输入字段,以便只有按钮可见,从而调用过滤器,就像可以在 Azure DevOps 门户中找到的以下过滤器一样:
它必须是一个 CDK 覆盖面板,因为我不希望每当打开过滤器时屏幕的内容都会发生变化。
我尝试将 Mat-Select 与编程代码结合使用来模拟打开和关闭 Mat-Select 下拉列表。当输入字段隐藏时,这不起作用,即使打开和关闭它,它仍然保持隐藏状态。
我也尝试过仅隐藏 Mat-Select 指令的某些方面,但由于某种原因,CSS 样式没有生效。
我已经达到了下面的效果,剩下要做的就是隐藏右侧输入,单击按钮时,下拉菜单需要出现在按钮下方:
顺便说一句,所有这些过滤器选项都是动态的,并且作为可重用组件的一部分,可以注入到任何其他 HTML 中,并且只要提供特定的配置,它就会生成并发出过滤器。
下面是该组件的 HTML 和 TS 代码示例:
HTML:
<mat-card class="reusable-filter-mat-card">
<mat-card-content *ngIf="dropDownFilterConfig || checkBoxFilterConfig" class="parent-filter-style">
<ng-container *ngFor="let checkbox of checkBoxFilterConfig.config">
<button mat-button (click)="toggleCheckBox()">
<mat-icon class="material-symbols-outlined">instant_mix</mat-icon>
{{checkbox.title}}
</button>
<mat-form-field>
<mat-select mat-button [(value)]="selectedCheckbox" multiple hidden="true" #checkBoxFilter>
<ng-container *ngFor="let option of checkbox.data">
<mat-option [value]="option" (click)="onSelectCheckbox(option)">
<div *ngIf="checkbox.displayProperty; else stringProperty">
{{option[checkbox.displayProperty]}}
</div>
<ng-template #stringProperty>
{{option}}
</ng-template>
</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</ng-container>
</mat-card-content>
</mat-card>
TS:
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { CheckBoxFilterConfig, DropDownFilterConfig, FilterOutput } from './reusable-filter.interface';
import { MatSelect } from '@angular/material/select';
@Component({
selector: 'reusable-filter',
templateUrl: './reusable-filter.component.html',
styleUrls: ['./reusable-filter.component.scss']
})
export class ReusableFilterComponent implements OnInit {
// Input and Output
@Input() dropDownFilterConfig! : DropDownFilterConfig
@Input() checkBoxFilterConfig! : CheckBoxFilterConfig
@ViewChild(MatSelect) checkBoxFilter! : MatSelect;
@Output() FilterOutput = new EventEmitter<any>();
// Class Variables
isCheckBoxFilterOpen = false
isDropDownFilterOpen = false
selectedDropDown!: any
selectedCheckbox: any[] = []
appliedFilters: FilterOutput = {
dropDownFilter: [],
checkBoxFilter: []
}
ngOnInit(): void {
this.dropDownFilterConfig = {
enabled : true,
config : [
{
title : 'Personnel Filter',
data : [
{
name: 'John Kinsington',
title: 'Infrastructure Engineer'
},
{
name: 'Susan Burlsworth',
title: 'Infrastructure Engineer'
},
{
name: 'Macy McCready',
title: 'Infrastructure Engineer'
},
{
name: 'Mike Rinsworth',
title: 'Infrastructure Engineer'
}],
displayProperty: 'name'
}]
}
this.checkBoxFilterConfig = {
enabled : true,
config : [
{
title : 'Video Games',
data : [
{
name: 'Call of Duty',
rating: 5
},
{
name: 'Satisfactoy',
rating: 8.5
},
{
name: 'Dota 2',
rating: 9
},
{
name: 'Medal of Honour',
rating: 7.2
}],
displayProperty: 'name'
}]
}
}
onSelectDropdown(event: any){
console.log(event)
this.appliedFilters.dropDownFilter = event
console.log(this.appliedFilters)
this.isDropDownFilterOpen = !this.isDropDownFilterOpen
}
onSelectCheckbox(event: any){
this.appliedFilters.checkBoxFilter = event
console.log(this.appliedFilters)
}
toggleDropDown(){
this.isDropDownFilterOpen = !this.isDropDownFilterOpen;
}
toggleCheckBox(){
this.checkBoxFilter.toggle()
}
toggleOption(option: any) {
if (this.isSelected(option)) {
this.selectedCheckbox = this.selectedCheckbox.filter(selected => selected !== option);
} else {
this.selectedCheckbox.push(option);
}
}
isSelected(option: any): boolean {
return this.selectedCheckbox.includes(option);
}
emitSelectedFilters(){
this.FilterOutput.emit(this.appliedFilters)
}
}
任何想法或建议将不胜感激!
我看到您正在尝试创建由按钮触发的下拉过滤器,类似于您在 Azure DevOps 中看到的,同时保持输入字段隐藏。我在项目中也遇到过类似的需求,我想我可以帮助你。
首先,由于您希望通过按钮而不是通常的输入字段打开下拉菜单,因此您需要使用 Angular 的 ViewChild 以编程方式控制 mat-select 的打开。另外,要隐藏输入字段但保留功能,您可以使用一些 CSS 技巧。这里有一个方法:
HTML 更新:修改现有 HTML 以包含一个负责切换下拉列表的按钮。确保您的 mat-select 被模板变量引用,我们将在 TypeScript 文件中使用该变量。
<button mat-button (click)="toggleCheckBox()">{{checkbox.title}}</button>
<mat-form-field style="display:none;">
<mat-select #checkBoxFilter>
<!-- options go here -->
</mat-select>
</mat-form-field>
组件逻辑:在组件中,使用 ViewChild 获取对 MatSelect 的引用。然后,您可以使用此引用以编程方式打开和关闭下拉菜单。
@ViewChild('checkBoxFilter') checkBoxFilter: MatSelect;
toggleCheckBox() {
this.checkBoxFilter.toggle();
}
CSS 样式:为了确保只有按钮可见并且垫选择保持隐藏,请应用简单的 CSS 样式,例如 display: none;到 mat-form-field。
定位下拉菜单:既然您提到您不希望打开过滤器时屏幕内容发生变化,您可以考虑使用 Angular CDK 的 Overlay 面板来自定义下拉菜单的位置。这将允许您控制下拉菜单相对于按钮的显示位置。
通过这些步骤,单击按钮应切换下拉过滤器的可见性。此设置可确保实际的垫选择保持隐藏状态,不会影响您的布局,同时单击按钮时仍然有效。
我希望这有帮助!