Как отобразить двумерный массив с помощью *ngFor

#angular #ngfor

#angular #ngfor

Вопрос:

Я работаю над отрисовкой меню с подменю с использованием Angular7 * ngFor и столкнулся с проблемой при отрисовке двумерного массива. Мои данные json выглядят следующим образом:

 {
    "items": [
      {
        "id": 1,
        "name" : "Talent",
        "color" : "",
        "subItems" : [],
        "icon" : ""
      },
      {
        "id": 2,
        "name": "Connections",
        "color" : "",
        "isActivated" : false,
        "subItems" : [
            {
                "id" : 1,
                "name": "Pipelines",
                "color": "",
                "subItems" :[],
                "icon" : "fa fa-caret-down"
            },
            {
                "id" : 2,
                "name": "Requisition",
                "color": "",
                "subItems" :[],
                "icon" : ""
            },
            {
                "id" : 3,
                "name": "Projects",
                "color": "",
                "subItems" :[],
                "icon" : ""
            }
        ],
        "icon" : ""
      },
      {
        "id": 3,
        "name": "Intelligence",
        "color" : "",
        "isActivated" : false,
        "subItems" : [
            {
                "id" : 1,
                "name": "Companies",
                "color": "",
                "subItems" :[],
                "icon" : "fa fa-caret-down"
            },
            {
                "id" : 2,
                "name": "Schools",
                "color": "",
                "subItems" :[],
                "icon" : ""
            }
        ],
        "icon" : ""
      },
     ...
}
  

Строка меню, которую я хочу создать, имеет структуру, примерно такую:

https://codepen.io/marong125/pen/wOZgGz

Я реорганизовал данные и сохранил в двухмерных элементах массива, подобных этому:

 (2) [Array(3), Array(2)]
0: Array(3)
0: {id: 1, name: "Pipelines", color: "", subItems: Array(0), icon: "fa fa-caret-down"}
1: {id: 2, name: "Requisition", color: "", subItems: Array(0), icon: ""}
2: {id: 3, name: "Projects", color: "", subItems: Array(0), icon: ""}
length: 3
__proto__: Array(0)
1: Array(2)
0: {id: 1, name: "Companies", color: "", subItems: Array(0), icon: "fa fa-caret-down"}
1: {id: 2, name: "Schools", color: "", subItems: Array(0), icon: ""}
length: 2
  

Я создал часть с надстройкой, однако часть с подменю работает не очень хорошо. когда мне нравится это:

   <nav>
      <ul>
        <li class="sub-menu" *ngFor="let navItem of navItems" (click)="expand(navItem.name, $event.target)">
                <a href="#">{{navItem.name}}<span id="upDownIcons"><i *ngIf="navItem.subItems.length !== 0" [ngClass]="navIcons?.arrowDown" aria-hidden="true"></i></span></a>
          <ul>
            <ng-container *ngFor="let subItem of subItems; let i = index">
                <ng-container *ngFor="let item of subItem; let j = index">
                    <li ><a href="#">{{item.name}}</a></li>
                </ng-container>
            </ng-container>
          </ul>
        </li>
      </ul>
    </nav>
  

он отображается следующим образом: (каждому пункту меню присваивается одно и то же подменю):
введите описание изображения здесь

У кого-нибудь есть лучшие решения для правильного отображения двумерного массива? Большое вам спасибо!

Ответ №1:

Вы должны перебирать subItems массив navItem и то же самое для subItem .

 <li class="sub-menu" *ngFor="let navItem of navItems" (click)="expand(navItem.name, $event.target)">
  <a href="#">{{navItem.name}}<span id="upDownIcons"><i *ngIf="navItem.subItems.length !== 0" [ngClass]="navIcons?.arrowDown" aria-hidden="true"></i></span></a>
  <ul>
    <ng-container *ngFor="let subItem of navItem.subItems; let i = index"> // Iterate over subItems of navItem
      <ng-container *ngFor="let item of subItem.subItems; let j = index"> // The same here
        <li ><a href="#">{{item.name}}</a></li>
      </ng-container>
    </ng-container>
  </ul>
</li>
  

Комментарии:

1. Привет, Ритадж, спасибо за ответ. Однако после того, как я изменил код, выпадающее меню не может быть открыто. Ошибок консоли нет. мои навигационные элементы — это данные json.

Ответ №2:

Выполните итерацию по вашему navItems и используйте его index для итерации по его subItems

 <nav>
  <ul>
    <li class="sub-menu" *ngFor="let navItem of navItems;let i = index" (click)="expand(navItem.name, $event.target)">
            <a href="#">{{navItem.name}}<span id="upDownIcons"><i *ngIf="navItem.subItems.length !== 0" [ngClass]="navIcons?.arrowDown" aria-hidden="true"></i></span></a>
      <ul>
        <ng-container *ngFor="let subItem of subItems[i]; let j = index">

                <li ><a href="#">{{item.name}}</a></li>

        </ng-container>
      </ul>
    </li>
  </ul>
</nav>
  

Комментарии:

1. Привет, Сартак, я вставил твой код, однако выпадающее меню не может открыться. Ошибка консоли отсутствует

2. Можете ли вы поделиться своей функцией расширения.

3. развернуть(имя_элемента, цель): void { const CurrentItem = this.navItems.filter(элемент => item.name === имя_элемента); this.имя_элемента = имя_элемента; пусть currTarget = null; if (CurrentItem[0].Подпункты. длина !== 0) { if (target.tagName === ‘A’) { currTarget = target.parentNode; } else { currTarget = target; } currTarget.classList.toggle(‘активный’); } }

4. я бы рекомендовал отладить проблему, применив ваш active класс непосредственно к правильному html-элементу вместо его переключения