【问题标题】:Dynamically nested angular material menu动态嵌套的角度材质菜单
【发布时间】:2019-06-13 22:19:26
【问题描述】:

请告诉我如何解决以下问题: 我需要根据数据模型对象实现具有不同嵌套级别的动态创建菜单。目前,使用递归,我们设法创建了这样的菜单,但是,直接为子菜单分配属性 [matMenuTriggerFor] 存在问题。问题是所有后续子菜单实际上都是第一个子菜单,因此当您将鼠标悬停在任何子菜单上时,它会导致“翻转”到原始子菜单(图像上的示例:菜单,其中包括元素:设备、扩展、队列,队列成员(带有子菜单元素))。因此,在几秒钟内,我看到了另一个子菜单框架(图像上的示例:子菜单分组列表),之后第一个子菜单框架变为活动状态。当然,也许我没有做对所有事情,所以我转向这里。请帮帮我。谢谢大家。

imenu-item.ts

export interface IMenuItem {
  name: string | string[];
  link: string;
  subItems: IMenuItem[];
}

dynamic-menu.service.ts

import {Inject, Injectable} from '@angular/core';
import {APP_CONFIG_ROUTES} from '../../../config/routes/app.config.routes';
import {IAppConfigRoutes} from '../../../config/routes/iapp.config.routes';
import {IMenuItem} from './imenu-item';
import {_} from '@biesbjerg/ngx-translate-extract/dist/utils/utils';

@Injectable({
  providedIn: 'root'
})
export class DynamicMenuService {
  private readonly appConfig: any;

  constructor(@Inject(APP_CONFIG_ROUTES) appConfig: IAppConfigRoutes) {
    this.appConfig = appConfig;
  }

  getMenuItems(): IMenuItem[] {
    return [
      {
        name: _('labels.device'),
        link: '/' + this.appConfig.routes.device,
        subItems: null
      },
      {
        name: _('labels.extension'),
        link: '/' + this.appConfig.routes.extension,
        subItems: null
      },
      {
        name: _('labels.queue'),
        link: '/' + this.appConfig.routes.queue,
        subItems: null
      },
      {
        name: _('labels.queueMember'),
        link: null,
        subItems: [{
          name: _('labels.fullList'),
          link: '/' + this.appConfig.routes.queueMember.all,
          subItems: null
        }, {
          name: _('labels.groupedList'),
          link: '/' + this.appConfig.routes.queueMember.grouped,
          subItems: [{
            name: 'subName',
            link: 'subLink',
            subItems: [{
              name: 'subSubName1',
              link: 'subSubLink1',
              subItems: null
            }, {
              name: 'subSubName2',
              link: 'subSubLink2',
              subItems: null
            }]
          }]
        }]
      }
    ];
  }
}

dynamic-menu.component.ts

import {Component, Input, OnInit} from '@angular/core';
import {IMenuItem} from './imenu-item';

@Component({
  selector: 'app-dynamic-menu',
  templateUrl: './dynamic-menu.component.html',
  styleUrls: ['./dynamic-menu.component.scss']
})
export class DynamicMenuComponent implements OnInit {
  dynamicMenuItemsData: IMenuItem[];

  constructor(private dynamicMenuService: DynamicMenuService) {
  }

  ngOnInit() {
   this.dynamicMenuItemsData = this.dynamicMenuService.getMenuItems();
  }
}

dynamic-menu.component.html

<div>
  <ng-container [ngTemplateOutlet]="recursiveListMenuItems"
                [ngTemplateOutletContext]="{$implicit: dynamicMenuItemsData}">
  </ng-container>
</div>

<ng-template #recursiveListMenuItems let-listMenuItems>
  <div *ngFor="let menuItem of listMenuItems">
    <ng-container [ngTemplateOutlet]="menuItem.subItems != null ? subMenuItem : simpleMenuItem"
                  [ngTemplateOutletContext]="{$implicit: menuItem}">
    </ng-container>
  </div>
</ng-template>

<ng-template #simpleMenuItem let-menuItemArg>
  <a class="mat-button"
     mat-menu-item
     routerLink="{{menuItemArg.link}}">
    <span>{{menuItemArg.name | translate}}</span>
  </a>
</ng-template>

<ng-template #subMenuItem let-menuItemArg>
  <a class="mat-button"
     mat-menu-item
     routerLink="{{menuItemArg.link}}"
     [matMenuTriggerFor]="subItemsMenu">
    <span>{{menuItemArg.name | translate}}</span>
    <mat-menu #subItemsMenu="matMenu"
              [overlapTrigger]="false">
      <ng-container [ngTemplateOutlet]="recursiveListMenuItems"
                    [ngTemplateOutletContext]="{$implicit: menuItemArg.subItems}">
      </ng-container>
    </mat-menu>
  </a>
</ng-template>

【问题讨论】:

    标签: javascript angular typescript angular-material-6


    【解决方案1】:

    结果,结果证明,依赖于其他几个类似的问题。来自HERE(动态嵌套菜单示例)和来自HERE(mat-menu 的问题在打开时立即隐藏)的示例帮助解决了这个问题(在最后一个示例中,只需通过@ 更新zone.js 就足够了987654324@)

    【讨论】:

      【解决方案2】:

      很抱歉回答晚了,但也许您仍然会发现它有帮助。
      我编写了一个名为 ng-action-outlet 的小库,在我看来它做得非常好。


      看起来像这样:

      group: ActionGroup;
      
      constructor(private actionOutlet: ActionOutletFactory) {
          this.group = this.actionOutlet.createGroup();
      
          this.group.createButton().setIcon('home').fire$.subscribe(this.callback);
          this.group.createButton().setIcon('settings').fire$.subscribe(this.callback);
      }
      
      <ng-container *actionOutlet="group"></ng-container>
      

      演示https://stackblitz.com/edit/ng-action-outlet-demo?file=src/app/app.component.ts

      【讨论】:

      • 感谢您的回答。现在这个问题本身并不是特别相关,但将来我会尽量关注你的选择)
      猜你喜欢
      • 2019-06-02
      • 2015-12-29
      • 2019-03-04
      • 2018-06-17
      • 2020-09-06
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多