如何始终将 mat-menu 保持在同一位置?

时间:2021-03-23 01:50:19

标签: javascript css angular typescript angular-material

我有这个自定义下拉列表,我正在使用 mat-checkbox 来选择要选择的项目。无论如何,我的问题是,当我打开 mat-menu 然后选择项目(让我们选择 2 个项目)时,此时我的 ma​​t-menu 位于特定位置。现在,如果我关闭 mat-menu 并再次打开它,您会看到 mat-menu 处于更高的位置(它向上移动 5px 左右)。有谁知道即使在选择项目后如何始终将垫子菜单保持在同一位置?非常感谢。

注意:我尝试使用 disableOptionCentering 但它仅在 mat-select 上无法在 mat-menu 上使用

这是我的LIVE DEMO

<mat-menu #menu="matMenu" class="menu-select">
    <div (click)="$event.stopPropagation()">
        <ng-container *ngTemplateOutlet="chipList">
        </ng-container>
        <div *ngFor="let topping of toppingList">
            <mat-checkbox [checked]="listOfItems && listOfItems.indexOf(topping)>=0"
                (change)="change(topping,$event.checked)">
                {{topping}}
            </mat-checkbox>
        </div>
    </div>
</mat-menu>

2 个答案:

答案 0 :(得分:1)

在stackblitz中调试你的代码显示你在每次选择时改变了芯片列表,导致下拉面板高度和位置的重新计算。
所以问题更像是一个XY问题。
代码需要对保存值的数组进行一些重构。并使用管道而不是每次单击时运行的方法并重新排序 ngFor。 所以这是我的方法。

打字稿:

...
  toppingList = [
    { item: "item 1", selected: false },
    { item: "testing abc", selected: false },
    { item: "item 3", selected: false },
    { item: "Pepperoni", selected: false },
    { item: "Sausage", selected: false },
    { item: "Tomato", selected: false }
  ];
...



import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
  name: "myFilter",
  pure: false
})
export class MyFilter implements PipeTransform {
  transform(myArray: any[]) {
    return myArray.filter(item => item.selected);
  }


}

HTML:

<mat-menu #menu="matMenu" class="menu-select">
    <div (click)="$event.stopPropagation()">
        <ng-container *ngTemplateOutlet="chipList">
        </ng-container>
        <div *ngFor="let topping of toppingList">
            <mat-checkbox [checked]="topping.selected"
                (change)="topping.selected=!topping.selected">
                {{topping.item}}
            </mat-checkbox>
        </div>
    </div>
</mat-menu>
<ng-template #chipList>
    <mat-chip-list aria-label="Fruit selection">
        <mat-chip *ngFor="let fruit of (toppingList|myFilter)" removable="true">
            {{fruit.item}}
            <mat-icon matChipRemove (click)="fruit.selected=false">cancel</mat-icon>
        </mat-chip>
    </mat-chip-list>
</ng-template>

在此 demo 中,您可以看到菜单始终保持在同一位置,无需任何样式。您的代码将更轻巧且易读

答案 1 :(得分:0)

我不确定您是否有意使用 mat-menu 组件进行自定义多项选择,但这不是它的预期用途。

我建议使用带有 multiple property 的 mat-select 组件。更容易维护,看起来也更整洁

尽管您使用显示在下拉菜单中的筹码,但我认为这不是问题,它们不应该在下拉菜单中,这不是它的目的,并且从 UI/UX 的角度来看会让人感到困惑。

我做了一个 Stackblitz fork 来说明。

现在下拉菜单仍然显示在输入的顶部(默认行为)来改变它,看看 paneClass 属性。 Here's a SO post