角路由器链接活动嵌套菜单 [英] Angular router link active nested menu
问题描述
我正在尝试使用角度路线制作嵌套菜单。
I'm trying to make a nested menu with angular routes.
我需要的是将类应用于嵌套路线(如果处于活动状态)并将类应用于一个
What I need is to apply class to a nested route if it's active and apply class to a parent component if its child is active.
如何实现此目标?现在,我正在进行递归菜单构建,以便在需要多层嵌套时易于使用。
How do I achieve this? For now I'm doing recursive menu building for ease of use when I need multilevel nesting.
component.html
component.html
<a (click)="toggleActive()" [class.active]="isActive" [routerLink]="menuItem.link" *ngIf="menuItem.link; else noLink">
<i *ngIf="menuItem.faClass" class="fa fa-{{menuItem.faClass}}"></i>
{{menuItem.name}} <span *ngIf="menuItem.children && menuItem.children.length > 0" class="fa fa-chevron-down"></span>
</a>
<ng-container *ngIf="menuItem.children && menuItem.children.length > 0">
<ul class="nav child_menu" [class.active]="isActive" routerLinkActive="active"
*ngFor="let item of menuItem.children">
<li menu-item [menuItem]="item" (checkActive)="updateActiveState()"></li>
</ul>
</ng-container>
<ng-template #noLink>
<a (click)="toggleActive()" [class.active]="isActive">
<i *ngIf="menuItem.faClass" class="fa fa-{{menuItem.faClass}}"></i>
{{menuItem.name}} <span *ngIf="menuItem.children && menuItem.children.length > 0" class="fa fa-chevron-down"></span>
</a>
</ng-template>
component.ts
component.ts
@Component({
selector: '[menu-item]',
templateUrl: './menu-item.component.html',
styleUrls: ['./menu-item.component.scss'],
host: {
'[class.active]': 'hostActive && isActive',
'[class.active-sm]': 'hostActiveSm && isActive'
}
})
export class MenuItemComponent implements OnInit, AfterViewInit, OnChanges {
public menuSize;
public isActive = false;
@Input() menuItem: MenuItem;
@Output() checkActive: EventEmitter<void> = new EventEmitter<void>();
@ViewChild(MenuItemComponent) menuComponent: MenuItemComponent;
private hostActive = true;
private hostActiveSm = false;
@HostBinding('class') hostClass = this.hostActive && this.isActive ? 'active' : this.hostActiveSm && this.isActive ? 'active-sm' : '';
constructor(
private router: Router,
private uss: UiStateService,
) {
}
ngOnInit() {
this.uss.menuSubject.subscribe(msg => {
this.menuSize = msg;
if (this.menuSize === MenuSizes.sm) {
this.hostActive = false;
this.hostActiveSm = true;
} else {
this.hostActive = true;
this.hostActiveSm = false;
}
this.updateActiveState();
});
this.router.events.subscribe((e: Event) => {
if (e instanceof NavigationEnd) {
this.updateActiveState();
}
});
}
ngOnChanges() {
}
ngAfterViewInit() {
this.updateActiveState();
}
public toggleActive(): void {
this.isActive = !this.isActive;
// if (this.menuComponent) {
// this.menuComponent.isActive = true;
// }
}
private updateActiveState(): void {
// reset previous state
this.isActive = false;
if (this.menuComponent) {
this.menuComponent.isActive = false;
}
// Check state of item with no els
const url = this.router.url;
console.log('URL', url, 'Menu link', this.menuItem.link);
console.log(url.match('/' + this.menuItem.link + '$/'));
if (this.menuItem && this.menuItem.link && url.match('/' + this.menuItem.link + '$/')) {
this.isActive = true;
this.checkActive.emit();
}
if (this.menuComponent) {
console.log('Menu component');
console.log(this.menuComponent, this.menuComponent.menuItem.link);
this.isActive = true;
}
}
}
一种从组件了解其路由是否处于活动状态的方法?诀窍是我使用的是 [routerLink]
,而不是 routerLink
,这样我才能通过。
作为到根页面的链接。
Is there a way of knowing from a component whether its route is active? The trick is that I'm using [routerLink]
and not a routerLink
so that I can pass .
as a link to the root page.
最好我可以重新创建 stackblitz
尝试访问 Dasboard。它应该为父 li
添加一个活动类。如果您自己添加它,则会在其元素上看到已应用的类,并在右侧看到一个彩色的条。
The best I could recreate stackblitz
Try to visit "Dasboard". It should add an "active" class to parent li
. If you add it yourself you would see the applied class on it's element and a colored bar on the right.
推荐答案
我设法解决了这个问题。 StackBlitz
I've managed to workaround it. StackBlitz
主要是通过使用 setTimeOut
而不在 navigateEnd
事件,这样我就可以检查 isActive
的状态并获取值(如果没有setTimeout,则该值是从过去获取的,这意味着它在使用时不会更新)。它的工作方式有些棘手,但是有效
Mainly it's achieved by using setTimeOut
without a time in navigateEnd
event so that I can check the state of isActive
and get the value(if there is no setTimeout the value is gotten "from the past" meaning it's not updated when it's taken). It works in a bit tricky way but it works
这篇关于角路由器链接活动嵌套菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!