我们如何创建具有多级子级的角度的动态路线导航链接,这将在重新加载时重新创建整个导航

问题描述 投票:0回答:2

我想根据某些配置创建一个导航列表。 就像一个数组

export interface LeftNavModel {
name: string,
route: string,
iconName?: string,
data?: any }

所以导航数据看起来像这样

[
  {
    name: "First Route",
    route:"first",
    sectionName: "First Section",
    iconName: "home",
    children: [
      {
        name: "First Child Route",
        route:`first/firstChild`,
        iconName: "folder"
        children: [
          {
            name: "First Sub Child Route",
            route:"first/firstChild/firstSubChild",
            iconName: "image"
          }
        ]
      }
    ]
  }
]

此数据将创建导航链接,例如

并在组件中使用配置 JSON 中的路由创建 routerLink。 我能够创建相同的并且工作正常。问题是我想共享导航 URL,以便其他用户可以打开动态创建导航的同一页面。

页面刷新可以通过将配置保留为路由器中的状态来处理。或者使用任何存储机制,例如 localStorage。但是我们如何共享链接和配置数据。 将配置作为 queryParam 传递将创建巨大的 url。还有其他选择吗?

angular angular-ui-router
2个回答
0
投票

我必须在我不久前正在进行的一个项目中执行此操作。

我在侧边栏使用引导手风琴,因此需要为每个菜单项提供一个 id。你可以用任何东西完成同样的事情,尽管不一定是引导程序。

创建一个类来表示菜单/导航项(我的是这样的)

export class MenuItem {
  id: number;
  text: string;
  icon: string;
  url?: string;
  children?: MenuItem[];
}

创建一个菜单项数组,用于存储项目列表。这是我的简化版本:

export const menuItems = [
  {
    id: 1,
    text: 'Dashboard',
    icon: 'dashboard',
    url: 'dashboard',
  },
  {
    id: 2,
    text: 'Organizational Documents',
    icon: 'library_books',
    children: [
      {
        id: 3,
        text: 'View',
        icon: 'search',
        url: 'organizational-documents/view',
      },
    ],
  },
  {
    id: 4,
    text: 'Qualifications',
    icon: 'school',
    children: [
      {
        id: 5,
        text: 'Create',
        icon: 'create',
        url: 'qualifications/create',
      },
      {
        id: 6,
        text: 'View',
        icon: 'search',
        url: 'qualifications/view',
      },
    ],
  },
 {
    id: 7,
    text: 'Programmes',
    icon: 'library_books',
    children: [
      {
        id: 8,
        text: 'Create',
        icon: 'create',
        children: [
          {
            id: 9,
            text: 'Learnership',
            icon: 'add',
            url: 'programmes/create/learnership',
          },
          {
            id: 10,
            text: 'Internship',
            icon: 'add',
            url: 'programmes/create/internship',
          },
        ],
      },
{
        id: 11,
        text: 'View',
        icon: 'search',
        children: [
          {
            id: 12,
            text: 'Learnerships',
            icon: 'search',
            url: 'programmes/view/learnerships',
          },
          {
            id: 13,
            text: 'Internships',
            icon: 'search',
            url: 'programmes/view/internships',
          },
        ],
      },
]

从包含导航项的组件初始化菜单项

import { menuItems } from '../menuItems';

public ngOnInit() {
    this.renderMenu();
}

private renderMenu(): void {
  this.renderedMenuItems = JSON.parse(JSON.stringify(menuItems));
}

添加类似于下面的 HTML 以便迭代菜单项

 <nav id="sidebar" class="sidebar-open overflow-auto shadow">
    <div class="accordion accordion-flush mb-2" id="sidebarAccordion">
      <div *ngFor="let item of renderedMenuItems">
        <div *ngIf="!item.children">
          <a
            id="flush-{{ item.id }}"
            class="
              fs-6
              d-flex
              align-items-center
              p-2
              pt-3
              pb-3
              cursor-pointer
              non-dropdown
            "
            routerLink="{{ item.url }}"
            routerLinkActive="active-route-dash"
          >
            <mat-icon class="ms-1 me-3">{{ item.icon }}</mat-icon>
            {{ item.text }}
          </a>
        </div>
        <div *ngIf="item.children" class="accordion-item">
          <h2 class="accordion-header m-0" id="flush-{{ item.id }}">
            <div
              id="menu-button-{{ item.id }}"
              class="accordion-button collapsed cursor-pointer p-2"
              data-bs-toggle="collapse"
              attr.data-bs-target="#flush-collapse-{{ item.id }}"
              aria-expanded="false"
              attr.aria-controls="flush-collapse-{{ item.id }}"
            >
              <mat-icon class="ms-1 me-3">{{ item.icon }}</mat-icon>
              {{ item.text }}
            </div>
          </h2>
          <div
            id="flush-collapse-{{ item.id }}"
            class="accordion-collapse collapse"
            attr.aria-labelledby="flush-{{ item.id }}"
            data-bs-parent="#sidebarAccordion"
          >
            <ul class="list-unstyled mb-0">
              <li *ngFor="let child of item.children">
                <div
                  *ngIf="child.children"
                  class="accordion accordion-flush"
                  id="accordion-{{ child.id }}"
                >
                  <div class="accordion-item">
                    <h2 class="accordion-header m-0" id="flush-{{ child.id }}">
                      <div
                        id="menu-button-{{ child.id }}"
                        class="accordion-button collapsed cursor-pointer p-2"
                        data-bs-toggle="collapse"
                        attr.data-bs-target="#flush-collapse-{{ child.id }}"
                        aria-expanded="false"
                        attr.aria-controls="flush-collapse-{{ child.id }}"
                      >
                        <div class="ps-2 fw-normal d-flex align-items-center">
                          <mat-icon class="ms-1 me-3">{{
                            child.icon
                          }}</mat-icon>
                          {{ child.text }}
                        </div>
                      </div>
                    </h2>
                    <div
                      id="flush-collapse-{{ child.id }}"
                      class="accordion-collapse collapse"
                      attr.aria-labelledby="flush-{{ child.id }}"
                      attr.data-bs-parent="#accordion-{{ child.id }}"
                    >
                      <ul class="list-unstyled mb-0">
                        <li *ngFor="let subChild of child.children">
                          <a
                            class="
                              cursor-pointer
                              nav-item
                              ps-4
                              d-flex
                              align-items-center
                              non-dropdown
                            "
                            routerLink="{{ subChild.url }}"
                            routerLinkActive="active-route-3rd"
                          >
                            <mat-icon class="ms-1 me-3">{{
                              subChild.icon
                            }}</mat-icon>
                            {{ subChild.text }}
                          </a>
                        </li>
                      </ul>
                    </div>
                  </div>
                </div>
                <div *ngIf="!child.children">
                  <a
                    class="
                      cursor-pointer
                      nav-item
                      ps-3
                      d-flex
                      align-items-center
                      non-dropdown
                    "
                    routerLink="{{ child.url }}"
                    routerLinkActive="active-route-2nd"
                  >
                    <mat-icon class="ms-1 me-3">{{ child.icon }}</mat-icon>
                    {{ child.text }}
                  </a>
                </div>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </nav>

使用上面的代码,我最终得到以下结果(显然在样式之后)


0
投票

我已经针对此问题实施了解决方案,因为没有其他可用答案。我现在将分享我为满足要求而实施的内容。

我已经创建了一个配置,其中包含我的应用程序所需的所有导航。加载特定视图时,导航组件会加载所需的配置部分

配置示例

export const navConfig = [{
sectionName:"Search",
i18nKey: "search",
sectionTopDivider: true,
menuList:[
  {
    menuName: "Company1",
    i18nKey: "company1",
    route: "app/company1",
    prependIconName: "search",
    customClass:"text-success",
    appendIconName: "image",
  },
  {
    menuName: "Company2",
    i18nKey: "company2",
    route: "app/company2",
    prependIconName: "search",
    appendIconName: "image"
  }
]},{
sectionName:"OverView",
i18nKey:"OverView",
sectionTopDivider: true,
menuList:[
  {
    menuName: "Company 1 Overview",
    i18nKey: "company1 overview",
    route: "app/company1-overview",
    prependIconName: "home",
    appendIconName: "image",
    menuList: [
      {
        menuName: "Company1 Child Route",
        i18nKey: "",
        route: "company1/[departmentId]",
        prependIconName: "",
        appendSVGIconName: "",
      }
    ]
  },
  {
    menuName: "Company 2 Overview",
    i18nKey: "company2 overview",
    route: "app/company2-overview",
    prependIconName: "home",
    appendIconName: "image",
    menuList: [
      {
        menuName: "Company2 Child Route",
        i18nKey: "",
        route: "company2/[departmentId]",
        prependIconName: "",
        appendSVGIconName: "",
      }
    ]
  }
]}]

所有与应用程序相关的文件都附加到该代码片段中。 您可以将此导航组件插入到您的应用程序中,如下所示

<app-left-navbar></app-left-navbar>

要加载导航配置,请将导航服务注入构造函数并加载所需的导航配置 例如:

private navService: LeftNavbarService, 
this.navService.setNavConfigList(navConfig);

其中 navConfig 是根据模型 left-nav.model.ts 所需的导航配置

如果您想从配置中加载特定部分,您可以像下面这样做

this.route.url.subscribe(url=>{
  let headerModel: HeaderModel = {
    mainLabel: "New Header",
    mainIconName: "menu",
    subLabel: "Back to dashboard",
    subIconName: "arrow_back",
    subRoute: "./"
  }
  this.navService.setNavHeader(headerModel);  // new header model if required

  let defaultNavConfig = this.navService.getNavConfigList(); // featch loaded config from nav service
  let section = this.navService.getConfig(defaultNavConfig, 'sectionName', 'OverView'); //fetch required section from config using section name
  section.hidden = false; //edit section visibility if required

  this.navService.setNavList(defaultNavConfig); // set nav with updated config. You can edit already existing config or can add new config if required
}) 

请通过服务了解工作情况。

//left-navbar.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, take } from 'rxjs';
import { HeaderModel, LeftMenuConfig, MenuItemConfig } from '../models/left-nav.model';
import * as _ from 'lodash';
@Injectable({
  providedIn: 'root'
})
export class LeftNavbarService {

  navConfigList!: LeftMenuConfig[];//new BehaviorSubject<LeftMenuConfig[]>([]);
  navList = new BehaviorSubject<LeftMenuConfig[]>([]);
  headerModel = new BehaviorSubject<HeaderModel>(<HeaderModel>{});
  // footerModel = new BehaviorSubject<HeaderModel>(<HeaderModel>{});
  activeNavModel!: MenuItemConfig;
  constructor() { }

  getNavList(): Observable<LeftMenuConfig[]> {
    return this.navList.asObservable();
  }

  getNavConfigList(): LeftMenuConfig[] {
    return _.cloneDeep(this.navConfigList);
  }

  setNavList(navList: LeftMenuConfig[]) {
    this.navList.next(navList)
  }

  setNavConfigList(navList: LeftMenuConfig[]) {
    this.navConfigList = navList;
  }

  getNavHeader(): Observable<HeaderModel> {
    return this.headerModel.asObservable();
  }

  setNavHeader(headerModel: HeaderModel) {
    this.headerModel.next(headerModel);
  }

  // getNavFooter(): Observable<HeaderModel> {
  //   return this.footerModel.asObservable();
  // }

  // setNavFooter(footerModel: HeaderModel) {
  //   this.footerModel.next(footerModel);
  // }

  getNavListPromise() {
    return this.navList.pipe(take(1)).toPromise();
  }

  setActiveNavModel(navModel: MenuItemConfig) {
    this.activeNavModel = navModel;
  }

  getActiveNavModel() {
    return this.activeNavModel;
  }

  getConfig(listToMatch: Array<any>, key: string, value: string): any {
    let matched;
    for (let i = 0; i < listToMatch.length; i++) {
      let item = listToMatch[i];
      if (item[key] === value) {
        matched = item;
        break;
      }
      if (item.menuList && item.menuList.length) {
        matched = this.getConfig(item.menuList, 'menuName', value);
        if (matched) break;
      }
    }
    return matched;
  }
}

//left-nav.model.ts

export interface LeftMenuConfig {
    sectionName: string,
    i18nKey: string,
    sectionTopDivider?: boolean,
    sectionBottomDivider?: boolean,
    hidden?:boolean,
    menuList: MenuItemConfig[]
}

export interface MenuItemConfig {
    menuName: string,
    i18nKey: string,
    route: string,
    prependIconName?: ((item: MenuItemConfig) => string) | string,
    prependSVGIconName?: ((item: MenuItemConfig) => string) | string,
    appendIconName?: ((item: MenuItemConfig) => string) | string,
    appendSVGIconName?: ((item: MenuItemConfig) => string) | string,
    data?: any,
    rawHtml?: ((item: MenuItemConfig) => string) | string,
    customClass?: ((item: MenuItemConfig) => string) | string, 
    formatterComponent?: any,
    hidden?: boolean,
    disabled?:boolean,
    privilege?:string,
    selected?: boolean,
    menuList?: MenuItemConfig[]
}

export interface HeaderModel {
    mainLabel: string,
    mainRoute?: string,
    mainIconName?: string,
    mainSvgIconName?: string,
    subLabel?: string,
    subRoute?: string,
    subIconName?: string,
    subSvgIconName?: string,
}

//left-navbar.component.ts

import { Component, ElementRef, Input, OnInit } from '@angular/core';
import { ActivatedRoute, NavigationStart, Router } from '@angular/router';
import { filter, Observable } from 'rxjs';
import { HeaderModel, LeftMenuConfig, MenuItemConfig } from '../models/left-nav.model';
import { LeftNavbarService } from '../services/left-navbar.service';
import { animateText, onSideNavChange } from './left-nav-animations';

@Component({
  selector: 'app-left-navbar',
  templateUrl: './left-navbar.component.html',
  styleUrls: ['./left-navbar.component.scss'],
  animations: [onSideNavChange, animateText]
})
export class LeftNavbarComponent implements OnInit {
  constructor(
    private navbarService: LeftNavbarService,
    private route: ActivatedRoute,
    private router: Router
  ) {
    this.router.events
      .pipe(
        filter(event => event instanceof NavigationStart)
      )
      .subscribe(
        (event) => {
          let url = this.route.url;
          console.log(url);
        }
      );

  }

  navList!: Observable<LeftMenuConfig[]>;
  headerModel!: Observable<HeaderModel>;
  footerModel!: any;
  expanded = true;
  navState = true;
  @Input() leftPadding: number = 0; // Initial left padding of list item
  @Input() listNodePadding: number = 20 // Left padding of children list items for each level

  ngOnInit() {
    this.navList = this.navbarService.getNavList();
    this.headerModel = this.navbarService.getNavHeader();
    this.footerModel = {
      mainLabel: 'Help & Support',
      mainRoute: '',
      mainIconName: 'help_outline',
      subLabel: 'Help Sub Label',
      subRoute: '',
      subIconName: 'copyright',
    };
  }

  getCustomIcon(item: any, key: string) {
    if (item[key] && typeof (item[key]) === 'function') {
      return item[key](item);
    } else return item[key];
  }

  toggleLeftNav() {
    this.navState = !this.navState;
    setTimeout(() => {
      this.expanded = this.navState;
    }, 200)
  }

  onActivateRoute(isActive: boolean, item: MenuItemConfig) {
    if (isActive) {
      this.navbarService.setActiveNavModel(item);
    };
  }
}
//left-navbar.component.scss

.left-nav-container {
    ::ng-deep {
        .mat-list-item {
            height: 40px !important;
            align-items: center;

            // border-left: 4px solid transparent;
            // &.active {
            //     // border-left: 4px solid #303030;
            // }
            .mat-list-item-content {
                overflow: hidden;
                padding: 0 0 0 4px !important;
                width: 100%;
            }

            &:disabled {
                cursor: not-allowed;
                pointer-events: none;
                opacity: 0.6;
            }
        }

        .mat-subheader {
            padding: 0 !important;
        }

        .mat-nav-list.footer-section {
            margin-top: auto !important;
        }

        .mat-list-text {
            padding-left: 0 !important;
        }
    }

    &.expanded {
        // min-width: 220px;
    }

    &.collapsed {
        ::ng-deep {
            .mat-list-item {
                // width: 40px !important;
                justify-content: center;
            }
        }
    }

    .menu-group-container {
        padding: 0 4px;

        &.active-container {
            border-radius: 4px;
            background-color: #e8ecef80;
            padding: 4px;
        }
    }

    .active-container {
        border-radius: 4px;
        background-color: #e8ecef80;
        padding: 4px;
    }

}

.expandCollapseBtn {
    width: 24px;
    height: 24px;
    background-color: #8b9daf;
    border-radius: 50%;
    display: inline-block;
    right: -12px;
    top: 10px;
    z-index: 4;
    cursor: pointer;

    span.material-icons {
        color: white;
    }
}

.child-indicator-elm {
    position: absolute;
    width: 8px;
    height: 30px;
    z-index: 1;

    &::before {
        content: "";
        float: left;
        width: 8px;
        height: inherit;
        background: transparent;
        border: 2px solid #A3B1BF;
        border-bottom-left-radius: 6px;
        border-top: 0;
        border-right: 0;
        position: absolute;
        top: 0px;
        left: 0px;
    }

    &::after {
        content: "";
        float: right;
        width: 4px;
        height: 4px;
        border-radius: 50%;
        position: absolute;
        right: -3px;
        bottom: -1px;
        background-color: #A3B1BF;
    }

}

.display-none {
    display: none !important;
}
//left-navbar.component.html
<div [@onSideNavChange]="navState ? 'open' : 'close'" class="left-nav-container p-2 h-100 position-relative"
    [ngClass]="{'expanded':expanded, 'collapsed':!expanded}">
    <span class="expandCollapseBtn position-absolute" (click)="toggleLeftNav()">
        <span *ngIf="expanded" class="material-icons">arrow_left</span>
        <span *ngIf="!expanded" class="material-icons">arrow_right</span>
    </span>
    <div class="w-100 h-100 d-flex flex-column align-items-stretched justify-content-start">
        <ng-container *ngIf="headerModel | async">
            <ng-container *ngTemplateOutlet="headerTmpl; context:{item: headerModel | async, class: 'header-section'}">
            </ng-container>
        </ng-container>
        <mat-nav-list dense>
            <ng-container *ngFor="let item of navList | async">
                <ng-container *ngIf="!item?.hidden">
                    <mat-divider *ngIf="item?.sectionTopDivider"></mat-divider>
                    <span *ngIf="item?.sectionName && expanded" mat-subheader>{{item?.sectionName}}</span>
                    <ng-container *ngFor="let menuItem of item?.menuList">
                        <div [appUserPrivilege]="menuItem?.privilege" class="menu-group-container"
                            [ngClass]="{'p-0':!expanded, 'active-container': menuItem?.selected}">
                            <ng-container *ngIf="menuItem?.formatterComponent">
                                <app-formatter-navlink [navModel]="menuItem"></app-formatter-navlink>
                            </ng-container>
                            <ng-container *ngIf="menuItem?.rawHtml">
                                <a mat-list-item class="d-flex rounded" [routerLink]="menuItem?.route"
                                    routerLinkActive="active"
                                    [innerHTML]="menuItem | navCustomHandler : 'rawHtml' | safeHtml">
                                </a>
                            </ng-container>
                            <ng-container
                                *ngIf="!menuItem?.formatterComponent && !menuItem?.rawHtml && !menuItem?.hidden">
                                <div appCustomClassHandler [menuItem]="menuItem">
                                    <a [disabled]="menuItem?.disabled" mat-list-item
                                        (isActiveChange)="onActivateRoute($event,menuItem)"
                                        [routerLink]="menuItem?.route" class="d-flex rounded"
                                        [style.padding-left.px]="expanded ? leftPadding: 0"
                                        [routerLinkActiveOptions]="{exact: true}" [state]="{config: menuItem}"
                                        routerLinkActive="active">
                                        <mat-icon *ngIf="menuItem?.prependIconName" matListIcon
                                            [innerText]="menuItem | navCustomHandler: 'prependIconName'"></mat-icon>
                                        <mat-icon *ngIf="menuItem?.prependSVGIconName" mat-list-icon
                                            svgIcon="{{ getCustomIcon(menuItem, 'prependSVGIconName') }}"></mat-icon>
                                        <div class="ps-1" [@animateText]="expanded ? 'show' : 'hide'" matLine>
                                            {{menuItem?.i18nKey}}
                                        </div>
                                        <mat-icon *ngIf="menuItem?.appendIconName"
                                            [@animateText]="expanded ? 'show' : 'hide'"
                                            [innerText]="menuItem | navCustomHandler: 'appendIconName'"></mat-icon>
                                        <mat-icon class="d-flex" *ngIf="menuItem?.appendSVGIconName"
                                            [@animateText]="expanded ? 'show' : 'hide'"
                                            svgIcon="{{ getCustomIcon(menuItem, 'appendSVGIconName') }}"></mat-icon>
                                    </a>
                                </div>
                            </ng-container>
                            <ng-container *ngIf="!menuItem.hidden && menuItem?.menuList">
                                <ng-container
                                    *ngTemplateOutlet="navTmpl; context:{menuItem: menuItem, leftPadding: leftPadding + listNodePadding }">
                                </ng-container>
                            </ng-container>
                        </div>
                    </ng-container>
                    <mat-divider *ngIf="item?.sectionBottomDivider"></mat-divider>
                </ng-container>
            </ng-container>
        </mat-nav-list>
        <ng-container *ngIf="footerModel">
            <ng-container
                *ngTemplateOutlet="footerTmpl; context:{item: footerModel, class: 'footer-section', footer: true}">
            </ng-container>
        </ng-container>
    </div>
</div>

<ng-template #navTmpl let-parentConfig="menuItem" let-menuItem="menuItem" let-leftPadding="leftPadding">
    <mat-nav-list dense>
        <ng-container *ngFor="let menuItem of menuItem?.menuList; let i=index;">
            <ng-container *ngIf="menuItem && !menuItem?.hidden">
                <div [ngClass]="{'active-container':menuItem?.selected}" [appUserPrivilege]="menuItem?.privilege">
                    <ng-container *ngIf="menuItem?.formatterComponent">
                        <app-formatter-navlink [navModel]="menuItem"></app-formatter-navlink>
                    </ng-container>
                    <ng-container *ngIf="menuItem?.rawHtml">
                        <a mat-list-item class="d-flex rounded" [routerLink]="menuItem?.route" routerLinkActive="active"
                            [innerHTML]="menuItem.rawHtml(menuItem) | safeHtml">
                        </a>
                    </ng-container>
                    <ng-container *ngIf="!menuItem?.formatterComponent && !menuItem?.rawHtml">
                        <div class="position-relative" appCustomClassHandler [menuItem]="menuItem">
                            <span *ngIf="expanded" appFluidHeight [refElement]="linkRef" [parentConfig]="parentConfig"
                                [index]="i" [style.bottom.px]="linkRef['_element']?.nativeElement?.offsetHeight/2"
                                [style.left.px]="leftPadding" class="child-indicator-elm"></span>
                            <a #linkRef [disabled]="menuItem?.disabled" mat-list-item
                                [style.padding-left.px]="expanded ? leftPadding: 0" class="d-flex rounded"
                                (isActiveChange)="onActivateRoute($event,menuItem)" [routerLink]="menuItem?.route"
                                [state]="{config: menuItem}" routerLinkActive="active"
                                [routerLinkActiveOptions]="{exact: true}">
                                <mat-icon *ngIf="menuItem?.prependIconName" matListIcon
                                    [innerText]="menuItem | navCustomHandler: 'prependIconName'"></mat-icon>
                                <mat-icon *ngIf="menuItem?.prependSVGIconName" mat-list-icon
                                    svgIcon="{{ getCustomIcon(menuItem, 'prependSVGIconName') }}"></mat-icon>
                                <div class="ps-1" [@animateText]="expanded ? 'show' : 'hide'" matLine>
                                    {{menuItem?.i18nKey}}
                                </div>
                                <mat-icon *ngIf="menuItem?.appendIconName" [@animateText]="expanded ? 'show' : 'hide'"
                                    [innerText]="menuItem | navCustomHandler: 'appendIconName'"></mat-icon>
                                <mat-icon class="d-flex" *ngIf="menuItem?.appendSVGIconName"
                                    [@animateText]="expanded ? 'show' : 'hide'"
                                    svgIcon="{{ getCustomIcon(menuItem, 'appendSVGIconName') }}"></mat-icon>
                            </a>
                        </div>
                    </ng-container>
                    <ng-container *ngIf="menuItem?.menuList">
                        <ng-container
                            *ngTemplateOutlet="navTmpl; context:{menuItem: menuItem, leftPadding: leftPadding + listNodePadding}">
                        </ng-container>
                    </ng-container>
                </div>
            </ng-container>
        </ng-container>
    </mat-nav-list>
</ng-template>

<ng-template #headerTmpl let-item="item" let-class="class" let-isFooter="footer">
    <mat-nav-list [ngClass]="class" dense>
        <mat-divider *ngIf="isFooter"></mat-divider>
        <ng-container *ngIf="item?.mainLabel">
            <a mat-list-item [@animateText]="expanded ? 'show' : 'hide'" [ngClass]="{'d-flex mainLabel rounded': true}"
                [routerLink]="item?.mainRoute" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
                <mat-icon *ngIf="item.mainIconName" matListIcon>{{item?.mainIconName}}</mat-icon>
                <mat-icon *ngIf="item.mainSvgIcon" mat-list-icon svgIcon="{{ item.mainSvgIcon }}"></mat-icon>
                <div [@animateText]="expanded ? 'show' : 'hide'" matLine class="ms-2 ml-2">{{item?.mainLabel}}</div>
            </a>
        </ng-container>
        <ng-container *ngIf="item?.subLabel">
            <a mat-list-item [ngClass]="{'d-flex subLabel rounded': true}" [routerLink]="item?.subRoute"
                routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
                <mat-icon *ngIf="item.subIconName" matListIcon>{{item?.subIconName}}</mat-icon>
                <mat-icon *ngIf="item.subSvgIcon" mat-list-icon svgIcon="{{ item.subSvgIcon }}"></mat-icon>
                <div [@animateText]="expanded ? 'show' : 'hide'" matLine class="ms-2 ml-2">{{item?.subLabel}}</div>
            </a>
        </ng-container>
    </mat-nav-list>
</ng-template>

<ng-template #footerTmpl let-item="item" let-class="class">
    <mat-nav-list [ngClass]="class" dense>
        <mat-divider *ngIf="class"></mat-divider>
        <ng-container *ngIf="item?.mainLabel">
            <a mat-list-item [ngClass]="{'d-flex mainLabel rounded': true}" [routerLink]="item?.mainRoute"
                routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
                <mat-icon *ngIf="item.mainIconName" matListIcon>{{item?.mainIconName}}</mat-icon>
                <mat-icon *ngIf="item.mainSvgIcon" mat-list-icon svgIcon="{{ item.mainSvgIcon }}"></mat-icon>
                <div [@animateText]="expanded ? 'show' : 'hide'" matLine class="ms-2 ml-2">{{item?.mainLabel}}</div>
            </a>
        </ng-container>
        <ng-container *ngIf="item?.subLabel">
            <a mat-list-item [ngClass]="{'d-flex subLabel rounded': true}" [routerLink]="item?.subRoute"
                routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
                <mat-icon *ngIf="item.subIconName" matListIcon>{{item?.subIconName}}</mat-icon>
                <mat-icon *ngIf="item.subSvgIcon" mat-list-icon svgIcon="{{ item.subSvgIcon }}"></mat-icon>
                <div [@animateText]="expanded ? 'show' : 'hide'" matLine class="ms-2 ml-2">{{item?.subLabel}}</div>
            </a>
        </ng-container>
    </mat-nav-list>
</ng-template>

© www.soinside.com 2019 - 2024. All rights reserved.