Dynamic nested Material menu from json object in Angular 5

后端 未结 2 1105
轻奢々
轻奢々 2021-01-31 09:09

How to create dynamic nested menu from json object?

I started using Angular Material Design today for the first time and I\'m trying to create nested menus using materia

相关标签:
2条回答
  • 2021-01-31 09:32

    The following structure should work for you:

    <button mat-button [matMenuTriggerFor]="main_menu">My menu</button>
    
    <mat-menu #main_menu="matMenu">
      <ng-container *ngFor="let mainItem of objectKeys(my_menu)">
        <button mat-menu-item [matMenuTriggerFor]="sub_menu">{{ mainItem }}</button>
        <mat-menu #sub_menu="matMenu">
           <button *ngFor="let subItem of my_menu[mainItem]" mat-menu-item>{{ subItem }}</button>
        </mat-menu>
      </ng-container>
    </mat-menu>
    

    Since I placed sub_menu inside the embedded template (*ngFor) we can use the same name for template reference variable(#sub_menu).

    Stackblitz Example

    0 讨论(0)
  • 2021-01-31 09:46

    Here is a StackBlitz example of an arbitrarily deep nesting based on JSON (authored by @Splaktar)

    The key to arbitrary nesting is the self-referencing menu-item.component:

    import {Component, Input, OnInit, ViewChild} from '@angular/core';
    import {Router} from '@angular/router';
    import {NavItem} from '../nav-item';
    
    @Component({
      selector: 'app-menu-item',
      templateUrl: './menu-item.component.html',
      styleUrls: ['./menu-item.component.scss']
    })
    export class MenuItemComponent implements OnInit {
      @Input() items: NavItem[];
      @ViewChild('childMenu') public childMenu;
    
      constructor(public router: Router) {
      }
    
      ngOnInit() {
      }
    }
    
    <mat-menu #childMenu="matMenu" [overlapTrigger]="false">
      <span *ngFor="let child of items">
        <!-- Handle branch node menu items -->
        <span *ngIf="child.children && child.children.length > 0">
          <button mat-menu-item color="primary" [matMenuTriggerFor]="menu.childMenu">
            <mat-icon>{{child.iconName}}</mat-icon>
            <span>{{child.displayName}}</span>
          </button>
          <app-menu-item #menu [items]="child.children"></app-menu-item>
        </span>
        <!-- Handle leaf node menu items -->
        <span *ngIf="!child.children || child.children.length === 0">
          <button mat-menu-item [routerLink]="child.route">
            <mat-icon>{{child.iconName}}</mat-icon>
            <span>{{child.displayName}}</span>
          </button>
        </span>
      </span>
    </mat-menu>
    
    0 讨论(0)
提交回复
热议问题