我使用Angular 8和Angular Materials来构建一个多级菜单。我可以通过对每个级别使用递归来让菜单工作。我递归地调用显示菜单每个级别的相同指令。
这一切都工作,菜单按预期生成。但是,菜单的行为不符合预期。我看过的例子,当你悬停在一个项目上时,嵌套的项目被打开,如果你移离一个项目,它的子项目被关闭。
例如,这是我制作的一个简单版本:
https://stackblitz.com/edit/dynamic-sidenav-multi-level-menu-tvim5b?file=app/app.component.html
问题
我的问题是,当我创建菜单时,如果我点击一个项目,子菜单就会打开。然而,除非我完全点击菜单,否则我永远无法让子菜单关闭。它的行为与上面的例子不同。
问题
我怎样才能让我的例子像上面一样,当菜单项失去焦点时关闭菜单项(子菜单项)?
信息
我没有在StackBlitz中放置我的具体示例,因为我不拥有代码,并且它需要后端服务来支持实现。
我认为我的问题是因为我递归地构建菜单项,而[matMenuTriggerFor]
在下一个递归中引用菜单。
代码
sidenav-list.component.html
<mat-nav-list>
<!-- Add the Home item -->
<a mat-list-item routerLink="/home" (click)="onSidenavClose()"><mat-icon>home</mat-icon><span class="nav-caption">Home</span></a>
<!-- Recurse over the app-sidenav-item -->
<app-sidenav-item *ngFor="let item of navItems" [item]="item" [depth]="depth+1" [sidenavClose]="sidenavClose"></app-sidenav-item>
</mat-nav-list>
sidenav-item.component.html <app-sidenav-item>
<div>
<button mat-button *ngIf="depth === 1" [matMenuTriggerFor]="menu"><mat-icon>play_arrow</mat-icon>{{item.name | titlecase}}</button>
<button mat-menu-item *ngIf="depth > 1" [matMenuTriggerFor]="menu">{{item.name}}</button>
<mat-menu #menu="matMenu">
<button *ngIf="item.actions.getItems" mat-menu-item (click)="onItemSelected(item, 0)"><mat-icon>list</mat-icon>Get Items</button>
<button *ngIf="item.actions.updateItem" mat-menu-item (click)="onItemSelected(item, 1)"><mat-icon>edit</mat-icon>Update Items</button>
<button *ngIf="item.actions.addItem" mat-menu-item (click)="onItemSelected(item, 2)"><mat-icon>add</mat-icon>Add Item</button>
<app-sidenav-item *ngFor="let child of item.children" [item]="child" [depth]="depth+1" [sidenavClose]="sidenavClose"></app-sidenav-item>
</mat-menu>
</div>
屏幕打印
正如你所看到的,我可以在不同的节点上打开多个项目。我不能关闭前一个项目。此外,它只响应点击,而不是鼠标悬停。
1条答案
按热度按时间kyks70gy1#
事情是这样的,你必须对一些数据进行预处理,这意味着在你的对象中,你必须知道它是否有子对象,以启用更多的层次结构,你需要知道它来自哪个父对象,以过滤它来构建这个对象
你的html应该看起来像这样。因为你知道你可以去3 - 4级,你为这些级别生成模板,并在数据存在的时候玩数据。
MatMenu还有另一个名为matMenuTriggerData的@input,父项将使用它触发子项的数据。
请注意,最后一级没有更多触发器。
你可以为过滤后的数据写一个函数
每一项都会包含
value
、label
、parent
和hasChildren
不同级别的内容,可以直接用API挂接确保传入的对象有一个data
属性,参见functon getData您可以在https://stackblitz.com/edit/angular-yfslub上查看此解决方案
希望你能根据自己的需要进行修改。