Получение свойства не существует из-за ошибки типа в angular

Я пытаюсь создать складное меню в своем компоненте заголовка, и у меня возникли проблемы с правильным форматированием JSON в моем угловом проекте. Я продолжаю получать эту ошибку:

Ошибка: src/app/comComponents/header/header.comComponent.html:48:49 — ошибка. TS2339: свойство «подссылки» не существует для типа «{ title: string; свернуто: логическое значение; ссылки: { заголовок: строка; URL: строка; подссылки: { заголовок: строка; URL: строка; }[]; }[]; }'.

48 <li *ngFor="let sublink of item.sublinks" класс="подссылка">

Кажется, я не могу устранить эту ошибку самостоятельно, и мне нужна помощь.

Мой HTML-шаблон таков:

<li *ngFor = "let item of navigationItems; let i = index" class = "link">
            <a [href] = "item.url" class = "main-wrapper">{{ item.title }}</a>
            <a class = "d-inline-block main-wrapper" (click) = "toggleCollapse(i)" role = "button" [attr.aria-expanded] = "!item.collapsed" [attr.aria-controls] = "'navCollapse_' + i">
              <img *ngIf = "item.collapsed" src = "./assets/img/icons/plus.svg" alt = "plus-icon" class = "ms-3">
              <img *ngIf = "!item.collapsed" src = "./assets/img/icons/minus.svg" alt = "minus-icon" class = "ms-3">
            </a>
            <div [id] = "'navCollapse_' + i" class = "collapse link-collapse main-collapse" [class.show] = "!item.collapsed">
              <ul class = "sublink-wrapper">
                <li *ngFor = "let sublink of item.sublinks" class = "sublink">
                  <a [href] = "sublink.url">{{ sublink.title }}</a>
                </li>
              </ul>
            </div>
          </li>

Мой код TS такой:

export class HeaderComponent {
  constructor() { }

  navigationState: string = 'out';
  
  navigationItems = [
    {
      title: 'Lorem ipsum',
      collapsed: true,
      links: [
        {
          title: 'Lorem ipsum 1',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 1.1', url: 'some url' },
            { title: 'Lorem ispum 1.2', url: 'some url' },
            { title: 'Lorem ispum 1.3', url: 'some url' }
          ]
        },
        {
          title: 'Lorem ipsum 2',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 2.1', url: 'some url' },
            { title: 'Lorem ispum 2.2', url: 'some url' },
            { title: 'Lorem ispum 2.3', url: 'some url' },
            { title: 'Lorem ispum 2.4', url: 'some url' }
          ]
        },
        {
          title: 'Lorem ipsum 3',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 3.1', url: 'some url' },
            { title: 'Lorem ispum 3.2', url: 'some url' },
            { title: 'Lorem ispum 3.3', url: 'some url' }
          ]
        },
        {
          title: 'Lorem ipsum 4',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 4.1', url: 'some url' },
            { title: 'Lorem ispum 4.2', url: 'some url' },
            { title: 'Lorem ispum 4.3', url: 'some url' },
            { title: 'Lorem ispum 4.4', url: 'some url' },
            { title: 'Lorem ispum 4.5', url: 'some url' }
          ]
        },
      ]
    }
  ];

  ngOnInit(): void {
  }

  toggleCollapse(index: number): void {
    this.navigationItems[index].collapsed = !this.navigationItems[index].collapsed;
  }

}

🤔 А знаете ли вы, что...
JavaScript может выполняться как на стороне клиента (в браузере), так и на стороне сервера (с использованием Node.js).


1
51
2

Ответы:

Решено

Джароманда X говорит правильно, sublinks — это свойство объекта в links. Поэтому вам следует сначала перебрать «ссылки». И всего у вас должно быть 3 *ngFor (а не 2): над navigationItems, затем links, затем sublinks. Also you can consider removing *ngIf` и использовать тернарный оператор для src и alt. В итоге я ожидаю увидеть что-то вроде этого:

<li *ngFor = "let item of navigationItems; let i = index" class = "link">
      <a class = "main-wrapper" (click) = "toggleCollapse(i)" role = "button" [attr.aria-expanded] = "!item.collapsed" [attr.aria-controls] = "'navCollapse_' + i">
        {{ item.title }}
        <img [src] = "item.collapsed ? './assets/img/icons/plus.svg' : './assets/img/icons/minus.svg'" [alt] = "item.collapsed ? 'plus-icon' : 'minus-icon'" class = "ms-3">
      </a>
      <div [id] = "'navCollapse_' + i" class = "collapse link-collapse main-collapse" [class.show] = "!item.collapsed">
        <ul class = "sublink-wrapper">
          <li *ngFor = "let link of item.links" class = "sublink">
            <a [href] = "link.url">{{ link.title }}</a>
            <ul *ngIf = "!item.collapsed" class = "sub-sublink-wrapper">
              <li *ngFor = "let sublink of link.sublinks" class = "sub-sublink">
                <a [href] = "sublink.url">{{ sublink.title }}</a>
              </li>
            </ul>
          </li>
        </ul>
      </div>
    </li>

constructor() { }

  navigationState: string = 'out';
  
  navigationItems:any = [
    {
      title: 'Lorem ipsum',
      collapsed: true,
      links: [
        {
          title: 'Lorem ipsum 1',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 1.1', url: 'some url' },
            { title: 'Lorem ispum 1.2', url: 'some url' },
            { title: 'Lorem ispum 1.3', url: 'some url' }
          ]
        },
        {
          title: 'Lorem ipsum 2',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 2.1', url: 'some url' },
            { title: 'Lorem ispum 2.2', url: 'some url' },
            { title: 'Lorem ispum 2.3', url: 'some url' },
            { title: 'Lorem ispum 2.4', url: 'some url' }
          ]
        },
        {
          title: 'Lorem ipsum 3',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 3.1', url: 'some url' },
            { title: 'Lorem ispum 3.2', url: 'some url' },
            { title: 'Lorem ispum 3.3', url: 'some url' }
          ]
        },
        {
          title: 'Lorem ipsum 4',
          url: 'some-url',
          sublinks: [
            { title: 'Lorem ispum 4.1', url: 'some url' },
            { title: 'Lorem ispum 4.2', url: 'some url' },
            { title: 'Lorem ispum 4.3', url: 'some url' },
            { title: 'Lorem ispum 4.4', url: 'some url' },
            { title: 'Lorem ispum 4.5', url: 'some url' }
          ]
        },
      ]
    }
  ];

  ngOnInit(): void {
  }

  toggleCollapse(index: number): void {
    this.navigationItems[index].collapsed = !this.navigationItems[index].collapsed;
  }

}
<li *ngFor = "let item of navigationItems; let i = index" class = "link">
    <a [href] = "item?.url" class = "main-wrapper">{{ item.title }}</a>
    <a class = "d-inline-block main-wrapper" (click) = "toggleCollapse(i)" role = "button" [attr.aria-expanded] = "!item.collapsed" [attr.aria-controls] = "'navCollapse_' + i">
      <img *ngIf = "item.collapsed" src = "./assets/img/icons/plus.svg" alt = "plus-icon" class = "ms-3">
      <img *ngIf = "!item.collapsed" src = "./assets/img/icons/minus.svg" alt = "minus-icon" class = "ms-3">
    </a>
    <div [id] = "'navCollapse_' + i" class = "collapse link-collapse main-collapse" [class.show] = "!item.collapsed">
      <ul class = "sublink-wrapper">
        <li *ngFor = "let sublink of item?.sublinks" class = "sublink">
          <a [href] = "sublink.url">{{ sublink.title }}</a>
        </li>
      </ul>
    </div>
  </li>