我应该将 *ngFor 嵌套在 *ngFor 中以获得动态 menu/category 吗?

Should I nest *ngFor inside *ngFor for a dynamic menu/category?

我想制作一个来自我的 API 的动态菜单,这样我就可以 add/remove 来自我应用程序“仪表板”的类别。

目前我有一个硬编码的HTML如下

<button mat-button class="extras" (click)="toggleDropdown('clothing')">CLOTHINGS <span class="additional">+</span></button>
    <div [ngClass]="{'show' : shows.clothing}" class="dropdown clothing">
        <button mat-menu-item routerLink="category/clothing">All</button>
        <button mat-menu-item>Corsets</button>
        <button mat-menu-item class="extras" (click)="toggleDropdown('dresses')">Dresses<span class="additional">+</span></button>
            <div [ngClass]="{'show' : shows.dresses}" class="dropdown dresses">
                <button mat-menu-item> Maxi Dresses</button>
                <button mat-menu-item> Midi Dresses</button>
                <button mat-menu-item> Mini Dresses</button>
            </div>
        <button mat-menu-item>Denim</button>
        <button mat-menu-item>Tops</button>
        <button mat-menu-item class="extras" (click)="toggleDropdown('bottoms')">Bottoms<span class="additional">+</span></button>
            <div [ngClass]="{'show' : shows.bottoms}" class="dropdown bottoms">
                <button mat-menu-item>Trousers</button>
                <button mat-menu-item>Skirts</button>
                <button mat-menu-item>Shorts</button>
                <button mat-menu-item>Playsuits</button>
            </div>
        <button mat-menu-item>Loungewear</button>
        <button mat-menu-item>Outerwear</button>
        <button mat-menu-item>Sweats</button>
    </div>

<button mat-button class="extras" (click)="toggleDropdown('collections')">BY COLLECTIONS <span class="additional">+</span></button>
    <div [ngClass]="{'show' : shows.collections}" class="dropdown collections">
        <button mat-menu-item routerLink="category/collections">All</button>
        <button mat-menu-item>Summer Collection</button>
        <button mat-menu-item>Winter Collection</button>
        <button mat-menu-item>Spring Collection</button>
        <button mat-menu-item>Fall Collection</button>
    </div>

<button mat-button routerLink="accessories">ACCESSORIES</button>

我为菜单创建了一个 JSON,所以我会显示它而不是这个硬编码的 html

export const menu = [
    {
        name: "clothings",
        children: [
            { name: "all", path: "clothing/all"},
            { name: "corsets", path: "clothing/corsets"},
            { name: "dresses", children: [
                { name:"maxi dresses", path: "clothing/dresses/maxi-dresses"},
                { name:"midi dresses", path: "clothing/dresses/midi-dresses"},
                { name:"mini dresses", path: "clothing/dresses/mini-dresses"}
            ]},
            { name: "denim", path: "clothing/denim"},
            { name: "tops", path: "clothing/tops"},
            { name: "bottoms", children: [
                { name:"trousers", path: "clothing/bottoms/trousers"},
                { name:"skirts", path: "clothing/bottoms/skirts"},
                { name:"shorts", path: "clothing/bottoms/shorts"},
                { name:"playsuits", path: "clothing/bottoms/playsuits"},
            ]},
            { name: "loungewear", path: "clothing/loungewear"},
            { name: "outerwear", path: "clothing/outerwear"},
            { name: "sweats", path: "clothing/sweats"}
         ],
    },
    {
        name: "by collection",
        children: [
            { name: "all", path: "collection/all"},
            { name: "summer collection", path: "collection/summer-collection"},
            { name: "winter collection", path: "collection/winter-collection"},
            { name: "spring collection", path: "collection/spring-collection"},
            { name: "fall collection", path: "collection/fall-collection"}
        ]
    },
    {
        name: "accessories",
        children: [
            { name: "all", path: "accessories/all"},
            { name: "glasses", path: "accessories/glasses"},
            { name: "necklace", path: "accessories/necklace"},
        ]
    },
]

我暂时试过了

 <div *ngFor="let category of menu">
        <button mat-button class="extras" (click)="toggleDropdown(category.name)">{{category.name}}<span class="additional">+</span></button>
        <div *ngFor="let child of category.children">
            <div [ngClass]="{'show': shows[category.name]}" class="dropdown {{category.name}}">
                <button mat-menu-item (click)="child.children && toggleDropdown(child.name)">{{child.name}}</button>
                <div *ngFor="let subchild of child.children">
                    <div [ngClass]="{'show' : shows[subchild.name]}" class="dropdown {{subchild.name}}">
                        <button mat-menu-item>{{subchild.name}}</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

这会正确显示 parents 类别及其子类别(“服装”、“按系列”和“配饰”显示其 children 基于 ngClass

但是他们孩子的子children不工作。

我想知道我是否使用了正确的方法,因为在我看来,所有这些 *ngFor

似乎有点混乱

尝试使用 mat-menu 的 'matMenuTriggerFor' 属性作为嵌套菜单选项,而不是使用嵌套 for 循环。

<mat-menu #myMenu="matMenu">
        <!-- menu option without sub menus -->
        <button mat-menu-item (click)='someFunction()'>Call function</button> 
        <!-- menu option with sub menus -->
        <button mat-menu-item [matMenuTriggerFor]="subMenu">Show sub menu</button>
      </mat-menu>

      <mat-menu #subMenu="matMenu">
          <button mat-menu-item>subOpt1</button>
          <button mat-menu-item>subOpt2</button>
      </mat-menu>

因此,因为您有嵌套的动态菜单,所以您可以使用不同的标签和 ngFor 循环分别呈现每个动态子菜单。最后,您可以 link 子菜单到主菜单,使用 'matMenuTriggerFor' 属性

您可以在下面查看更多示例 link: https://material.angular.io/components/menu/overview#menu-nested