Angular 中嵌套导航结构的有效方法

Efficient approach to nested navigation structure in Angular

假设我有以下树结构:

    Item1            Item2            Item3            Item4             Itemn  
  /   |   \        /   |   \        /   |   \        /   |   \         /   |   \
 /    |    \      /    |    \      /    |    \      /    |    \       /    |    \
 a    b    c      d    e    f      g    h     i     j    k     l     n-2   n-1   n

a,b,...,n 中的每个节点都有值。 构建此导航的更有效方式是什么?

他遵循我的方法:

创建一个包含布尔值的数组toggleStatus。 为每个选项卡分配一个编号,分别等于 toggleStatus 的索引。 方法 toggle(index) 将在索引 index.

处切换 toggleStatus 的值

请查看我的 Stackblitz 示例。

这里我有一些通过数组的示例代码 在你的 ts

 toggleArray = [{ name:'Item 1',subItems: [{name:'a',msg:'this is a',isExpand:false},{name:'b',msg:'this is b',isExpand:false},{name:'c',msg:'this is c',isExpand:false}] ,isExpand : false},{ name:'Item 2',subItems: [{name:'d',msg:'this is d',isExpand:false},{name:'e',msg:'this is e',isExpand:false},{name:'f',msg:'this is f',isExpand:false}] ,isExpand : false}]
  toggleItem(item) {
    item.isExpand = item.isExpand ? false:true;
    item.subItems.forEach((item) => {
      item.isExpand = false;
    })
  }
  toggleSubItem(subitem) {
    subitem.isExpand = subitem.isExpand ? false:true;
  }

在你的 HTML 中。我只是把逻辑放在你需要的地方 CSS。

<div *ngFor="let item of toggleArray" (click)="toggleItem(item)" class="p-4 bg-blue-600 text-white hover:bg-blue-400 cursor-pointer text-center">
    {{item.name}}
     <div class="container mx-auto">
    <div *ngIf="item.isExpand" class="flex flex-row justify-between">
      <div *ngFor="let subitem of item.subItems" (click)="toggleSubItem(subitem)" class="py-3 w-1/3 text-center bg-blue-200">
        {{subitem.name}}
        <div class="container mx-auto">
          <div *ngIf="subitem.isExpand" class="flex flex-row justify-between">
            <div  (click)="toggleSubItem(subitem)" class="py-3 w-1/3 text-center bg-blue-200">
              {{subitem.msg}}
            </div>
           </div>
          </div>
      </div>
    </div>
  </div>
  </div>

您不需要将所有数据直接添加到 HTML。您可以只创建一个对象数组,这将使其非常适合嵌套 ngFor 情况。

您的数据将如下所示

menus: any[] = [{
    item: 'Item 1', submenus: [
        { item: 'a', info: 'Info of a' },
        { item: 'b', info: 'Info of b' },
        { item: 'c', info: 'Info of c' }
    ]
}, {
    item: 'Item 2', submenus: [
        { item: 'd', info: 'Info of d' },
        { item: 'e', info: 'Info of e' },
        { item: 'f', info: 'Info of f' }
    ]
}, {
    item: 'Item 3', submenus: [
        { item: 'g', info: 'Info of g' },
        { item: 'h', info: 'Info of h' },
        { item: 'i', info: 'Info of i' }
    ]
}, {
    item: 'Item 4', submenus: [
        { item: 'j', info: 'Info of j' },
        { item: 'k', info: 'Info of k' },
        { item: 'l', info: 'Info of l' }
    ]
}];

然后在您的 HTML 中,我们将使用 ngFor

遍历 menus
<div *ngFor="let menu of menus; let i = index">
    <!-- Menu -->
    <div (click)="toggleMenu(i)" class="text-white cursor-pointer text-center">
        <div class="py-4 bg-blue-600 hover:bg-blue-400">
            {{menu.item}}
        </div>
        <div class="container" *ngIf="showSubmenu[i]">
            <!-- Submenus -->
            <ng-container *ngFor="let submenu of menu.submenus; let j = index">
                <div (click)="toggleSubmenu($event, submenu.item)" class="py-3 w-1/3 inline-block"
                    [ngClass]="{'bg-blue-200': j === 0, 'bg-blue-300': j === 1, 'bg-blue-400': j === 2}">
                    {{submenu.item}}
                </div>
            </ng-container>
            <!-- Information -->
            <div *ngFor="let submenu of menu.submenus; let j = index">
                <div *ngIf="showInfo[submenu.item]" (click)="$event.stopPropagation()" class="py-3 bg-green-400">
                    {{submenu.info}}
                </div>
            </div>
        </div>
    </div>
</div>

在您的组件中,我们将定义标志和 toggle 函数。我使用了一个数组作为标志。我们将根据索引动态地将切换标志插入到这个数组中。 $event.stopPropagation 用于防止 click 事件冒泡到父元素的 click 事件中。组件的外观如下

showSubmenu: any[] = [];
showInfo: any[] = [];

toggleMenu(index: number) {
    this.showSubmenu[index] = !this.showSubmenu[index];
}

toggleSubmenu(event: MouseEvent, item: string) {
    event.stopPropagation();
    this.showInfo[item] = !this.showInfo[item];
}

Note: The item passed to thetoggleSubmenu should be a unique value. If you have an id, it would be preferred to use that here instead of item.

这是相同的工作 StackBlitz