每行垫表的上下文菜单,带有多个子菜单。如何添加带有多个子菜单的自定义菜单?

问题描述 投票:0回答:1

我需要每行垫表一个上下文菜单,其中包含多个子菜单。如何添加具有多个子菜单的自定义菜单?我需要使用 Angular 11 和 Angular Material 11。

你能帮我解决这个代码吗?

这是我当前的代码,我只能使用主子菜单

HTML 文件

  <td
    mat-cell
    *matCellDef="let row"
    class="custom-table-cell"
    [style.width]="columnsConfiguration[column].width"
    (contextmenu)="
      currentTableOptions.showMenuActions &&
        currentRowMenuActions.length &&
        onContextMenu(row, $event)
    ">
...
<!-- START Menu per row -->
<span
  #contextMenuTrigger
  style="visibility: hidden; position: fixed"
  [style.left]="contextMenuPosition.x"
  [style.top]="contextMenuPosition.y"
  [matMenuTriggerFor]="contextMenu"
  (menuOpened)="hasContextMenu = true"
  (menuClosed)="hasContextMenu = false"></span>

<mat-menu
  #contextMenu="matMenu"
  backdropClass="actions-selector-menu-backdrop"
  class="actions-selector-menu">
  <ng-template
    matMenuContent
    let-row="row">
    <button
      mat-menu-item
      *ngFor="let rowMenuAction of currentRowMenuActions"
      (click)="onRowMenuAction(row, rowMenuAction, $event)"
      [disabled]="
        rowMenuAction.isDisabled ? rowMenuAction.isDisabled(row) : false
      ">
      {{ rowMenuAction.translateKey | translate }}
    </button>
  </ng-template>
</mat-menu>
<!-- END Menu per row -->

TS 文件。我创建了一个上下文菜单内容

  // Menu per row
  @ViewChild('contextMenuTrigger', { read: MatMenuTrigger })
  contextMenu!: MatMenuTrigger;
  contextMenuPosition = { x: '0px', y: '0px' };
  onContextMenu(row: T, event: MouseEvent) {
    event.preventDefault();

    this.contextMenuPosition.x = event.clientX + 'px';
    this.contextMenuPosition.y = event.clientY + 'px';

    this.contextMenu.menuData = { row };
    this.contextMenu.menu.focusFirstItem('mouse');
    this.contextMenu.openMenu();
  }

  // Actions per menu row
  @Input() set rowMenuActions(value: RowMenuAction<T>[]) {
    this.currentRowMenuActions = value;
  }
  currentRowMenuActions: RowMenuAction<T>[] = [];

  @Output() rowMenuAction = new EventEmitter<RowMenuActionEvent<T>>();
  onRowMenuAction(row: T, action: RowMenuAction<T>, event: Event) {
    this.rowMenuAction.emit({ row, action, event });
  }

谢谢!

angular angular-material angular-material-table
1个回答
0
投票

解决方案是下一个:

context-menu.component.html

<mat-menu
  #menu="matMenu"
  backdropClass="actions-selector-menu-backdrop"
  class="actions-selector-menu"
  [overlapTrigger]="false">
  <ng-template
    matMenuContent
    let-row="row">
    <ng-container *ngFor="let rowMenuAction of currentRowMenuActions">
      <!-- Handle branch node menu items -->
      <ng-container
        *ngIf="rowMenuAction.children && rowMenuAction.children.length > 0">
        <button
          mat-menu-item
          color="primary"
          [matMenuTriggerFor]="submenu.menu"
          [matMenuTriggerData]="{ row: row }">
          {{ rowMenuAction.translateKey | translate }}
        </button>

        <talan-context-menu
          #submenu
          [rowMenuActions]="rowMenuAction.children"
          (rowMenuAction)="onRowMenuAction($event)"></talan-context-menu>
      </ng-container>

      <!-- Handle leaf node menu items -->
      <button
        *ngIf="!rowMenuAction.children || rowMenuAction.children.length === 0"
        mat-menu-item
        (click)="
          onRowMenuAction({ row: row, action: rowMenuAction, event: $event })
        "
        [disabled]="
          rowMenuAction.isDisabled ? rowMenuAction.isDisabled(row) : false
        ">
        {{ rowMenuAction.translateKey | translate }}
      </button>
    </ng-container>
  </ng-template>
</mat-menu>

上下文菜单.component.ts

import {
  Component,
  EventEmitter,
  Input,
  Output,
  ViewChild,
} from '@angular/core';
import { MatMenu } from '@angular/material/menu';
import { RowMenuAction, RowMenuActionEvent } from '../../models/models';

@Component({
  selector: 'talan-context-menu',
  templateUrl: './context-menu.component.html',
  styleUrls: ['./context-menu.component.scss'],
})
export class ContextMenuComponent<T> {
  @ViewChild('menu', { static: true }) menu!: MatMenu;

  // Actions per menu row
  @Input() set rowMenuActions(value: RowMenuAction<T>[]) {
    this.currentRowMenuActions = value;
  }
  currentRowMenuActions: RowMenuAction<T>[] = [];

  @Output() rowMenuAction = new EventEmitter<RowMenuActionEvent<T>>();
  onRowMenuAction(event: RowMenuActionEvent<T>) {
    this.rowMenuAction.emit(event);
  }
}

table.component.html

      <td
        mat-cell
        *matCellDef="let row"
        (contextmenu)="
        onContextMenu(row, $event)">

<span
  #contextMenuTrigger="matMenuTrigger"
  style="visibility: hidden; position: fixed"
  [style.left]="contextMenuPosition.x"
  [style.top]="contextMenuPosition.y"
  [matMenuTriggerFor]="contextMenu.menu"
  (menuOpened)="hasContextMenu = true"
  (menuClosed)="hasContextMenu = false"></span>

<context-menu
  #contextMenu
  [rowMenuActions]="currentRowMenuActions"
  (rowMenuAction)="onRowMenuAction($event)"></context-menu>

表.组件.ts

  @ViewChild('contextMenuTrigger') contextMenuTrigger!: MatMenuTrigger;
  @ViewChild('contextMenu') contextMenu!: ContextMenuComponent<T>;

  contextMenuPosition = { x: '0px', y: '0px' };
  onContextMenu(row: T, event: MouseEvent) {
    event.preventDefault();

    this.contextMenuPosition.x = event.clientX + 'px';
    this.contextMenuPosition.y = event.clientY + 'px';

    this.contextMenuTrigger.menu.focusFirstItem('mouse');
    this.contextMenuTrigger.menuData = { row };
    this.contextMenuTrigger.openMenu();
  }
© www.soinside.com 2019 - 2024. All rights reserved.