具有可折叠列表的Angular2 sidenav:仅保持一个子列表打开

Angular2 sidenav with collapsible list: keeping only one sublist open

我有一个使用 Angular 2、TypeScript 和 Material 设计组件的 sidenav 演示。在 sidenav 上有一个 UL,UL 中的站点和用户锚展开以显示它们自己的子列表。

Plunker here

这是sidenav的HTML:

<md-sidenav #start mode="over" class="sideDrawer">
    <ul class="sidenav">
      <li><a>Dashboard</a></li>
      <li>
        <a (click)="sideNavClick()">Sites</a>
          <div>
            <ul *ngIf="clickedSites" class="sublist">
                <li><a (click)='sideNavAlert()'>All Sites</a></li>
                <li><a>Site Groups</a></li>
            </ul>
          </div>
      </li>
      <li>
        <a (click)="sideNavClickUser()">Users</a>
          <div>
            <ul *ngIf="clickedUsers" class="sublist">
                <li><a (click)="sideNavAlert()" >Add User</a></li>
                <li><a>Edit User</a></li>
                <li><a>Remove User</a></li>
            </ul>
          </div>
      </li>
      <li>
          <a>Lights</a>
      </li>
      <li><a>Settings</a></li>
    </ul>
</md-sidenav>

这是我的解决方案的一个非常简单的实现,但我真正的 sidenav 将在 sidenav 中有更多的导航选项,并且所有的子项都需要显示或隐藏。但是,我一次只希望显示一个子列表。我不希望每个子列表都有一个布尔值并使用 *ngIf 来显示和隐藏它们,并且在翻转布尔值的组件中有一些主函数。我希望有更精简的东西,但我不知道 Angular 2 有什么可能。我知道我也许可以做一个 CSS 解决方案,但我认为这也会迫使我向每个单独的列表添加和删除 类,就像在我的另一个列表中翻转每个单独列表的布尔值一样潜在的解决方案。

任何ideas/tips?

一种解决方案是将(单个)当前打开的菜单存储在一个变量中。每当单击可扩展菜单项时,菜单将关闭(如果它已打开)或打开,同时关闭当前打开的菜单。

组件:

export class AppComponent {
    clicked: string = null;

    sideNavClick(clicked: string): void {
        this.clicked = this.clicked == clicked ? null : clicked;
    }

    sideNavAlert(): void {
        alert("sublist item clicked");
    }
}

和模板文件:

<a (click)="sideNavClick('sites')">Sites</a>
<div>
    <ul *ngIf="clicked == 'sites'" class="sublist">...</ul>
</div>

...

<a (click)="sideNavClick('users')">Users</a>
<div>
    <ul *ngIf="clicked == 'users'" class="sublist">...</ul>
</div>

作为旁注;我肯定会建议在组件中创建一个数组,基于该数组自动生成菜单以避免必须键入所有可能性。

Here is the modified Plunker.