我的设置如下:
<nav>
<li>
<a someClassToggleDirective>Menu 1</a> <!-- This anchor element toggle determines if ul.sub-menu should be expanded (displayed) -->
<ul class="sub-menu"> <!-- This is displayed when it's first sibling 'a' has 'open' class -->
<li routerLinkActive="active"><a routerLink="childComp1">Child Component 1</a></li>
<li routerLinkActive="active"><a routerLink="childComp2">Child Component 2</a></li>
...
</ul>
</li>
<li>
<a someClassToggleDirective>...</a>
<ul class="sub-menu">
...
</ul>
</li>
...
</nav>
<router-outlet></router-outlet>
要加载任何组件,请单击li
项,然后展开它的子菜单ul
。单击其中一个子菜单项会在<router-outlet></outlet>
中加载相应的组件,并将子菜单项设置为活动。然后路线将是[root]/childComp1
。但是,如果我使用浏览器的地址栏直接导航到[root]/childComp1
,则会加载该组件,但不会展开活动子组件的父ul
。
那么,我该如何扩展呢?要展开子菜单(ul
),我需要在其兄弟open
中添加一个类a
。我该怎么做呢?我想到的一种方法是使用this.router.url
来确定组件,并根据路径名称展开相应的sub-menu
。但我觉得这不是最好的方法。有没有更好的方法?我想避免使用像jQuery这样的第三方库。
答案 0 :(得分:1)
您可以使用@ContentChildren
装饰器在子菜单中获取RouterLinkActive
的所有实例。并检测是否存在活动链接。
例如,您可以创建指令,该指令保留链接列表。并在每个路线上更改切换expand
prop。
<强>指令强>
import {Directive, HostListener, HostBinding, ContentChildren, QueryList} from '@angular/core';
import {Router, RouterLinkActive, NavigationEnd} from '@angular/router';
import 'rxjs/Rx';
import { Subscription } from 'rxjs/Subscription';
@Directive({ selector: '[listToggle]' })
export class ListToggleDirective {
// Collect RouterLinkActive instances
@ContentChildren(RouterLinkActive) links: QueryList<RouterLinkActive>;
// If expand=true - show submenu
@HostBinding('class.expand')
expand: boolean;
routerSub: Subscription;
constructor(private router: Router) {
}
ngAfterContentInit(): void {
// Detect if there is active links
this.routerSub = this.router.events
.filter(e => e instanceof NavigationEnd)
.subscribe(() => this.detectActiveLink());
}
ngOnDestroy(): void {
if (this.routerSub) {
this.routerSub.unsubscribe();
}
}
detectActiveLink(): void {
setTimeout(() => {
const hasActive = this.links.some(link => link.isActive);
this.expand = hasActive;
});
}
}
<强>用法强>
<ul>
<li listToggle>
<a>Open menu 1</a>
<ul class="sub-menu">
<a routerLink="/cmp1" routerLinkActive="active">cmp1</a>
<a routerLink="/cmp2" routerLinkActive="active">cmp2</a>
</ul>
</li>
<li listToggle>
<a>Open menu 2</a>
<ul class="sub-menu">
<a routerLink="/cmp3" routerLinkActive="active">cmp3</a>
</ul>
</li>
</ul>
<强>样式强>
li[listtoggle] {
&.expand .sub-menu {
display: block;
}
.sub-menu {
display: none;
}
}
希望这有帮助