创建具有多个子项的嵌套菜单栏/侧边栏

时间:2021-01-19 04:14:26

标签: javascript html css angular

Running code on Stackblitz is here

要求是让每个对象都可以点击,如果它有子对象,那么它下面的子对象应该在它下面打开,依此类推,直到最后一个子对象。

我已经能够遍历列表中的对象,但无法在对象的子对象内部循环,依此类推。

注意:不能使用任何 HTML/CSS/JS 库,必须从头开始创建。

import {
  Component,
  OnInit,
  Input
} from '@angular/core';

@Component({
  selector: 'ui-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
  itemList = [{
    id: 1,
    name: "Home",
    icon: 'home',
    child: [{
      id: 11,
      name: "Home1",
      icon: 'home',
      child: [{
        id: 111,
        name: "Home11",
        icon: 'home',
        child: []
      }]
    }, {
      id: 1111,
      name: "Home2",
      icon: 'home',
      child: []
    }]
  }, {
    id: 2,
    name: "Facility Management",
    icon: 'fac-mgmt',
    child: []
  }, {
    id: 3,
    name: "Engineering Services",
    icon: "engg-serv",
    child: []
  }];
  constructor() {}

  ngOnInit(): void {}
  openChild(item: any, index) {
    console.log(item.name)
  }
}
.text {
  text-align: left;
  font-size: 16px;
  letter-spacing: 0.11px;
  color: #214796;
}

ul {
  list-style-type: none;
  width: 25%;
  background-color: #ffffff;
  height: 100%;
  margin: 48px 8px 0 8px;
}

li {
  width: 296px;
  height: 48px;
  background: var(--neutral-20) 0% 0% no-repeat padding-box;
  background: #ffffff 0% 0% no-repeat padding-box;
  border-radius: 8px;
  opacity: 1;
  display: flex;
}
<ul>
  <div *ngFor="let item of itemList; let i=index" id="{{item.id}}">
    <li>
      <a class="text active" (click)="openChild(item, i)">{{item.name}}</a>
    </li>
  </div>
</ul>

1 个答案:

答案 0 :(得分:1)

这可以通过使用不同的组件来显示菜单栏的所有级别来简化和实现。
app.component.html

<menu *ngFor="let item of itemList" [item]="item"></menu>

现在管理此 menu 组件中子项的打开和关闭。为了提供更好的体验,我们使用布尔变量 expanded 来切换展开和折叠。

menu.component.html

<a style="cursor:pointer;color:#007db8;"(click)="onItemSelected(item)">
    {{item.name}}
</a>
<div *ngIf=" expanded">
    <menu *ngFor="let child of item.child" [item]="child">
    </menu>
</div>

menu.component.ts

 @Input() item;
 expanded: boolean = false;
 onItemSelected(item: any) {
 console.log("clicked");
 if (item.child && item.child.length) {
  this.expanded = !this.expanded;
  console.log("exp", this.expanded);
 }
}

这是working link of Stackblitz

enter image description here

PS:我没有根据您的要求添加任何角材料组件。如果允许,mat-list-itemmat-sidenav 可能是这里的最佳选择。如果需要,使用此 link 修改 CSS。

相关问题