角路由器链接活动嵌套菜单 [英] Angular router link active nested menu

查看:80
本文介绍了角路由器链接活动嵌套菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用角度路线制作嵌套菜单。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆