首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular @ViewChild魔法

Angular @ViewChild魔法
EN

Stack Overflow用户
提问于 2018-11-15 21:01:21
回答 1查看 248关注 0票数 0

我有一个以递归方式呈现的嵌套菜单。我需要在父母的元素上有活动的类,这样他们才会有压力。我试图通过将routerLinkActive赋值给id,然后通过@ViewChild从组件中检查它来实现它。

代码语言:javascript
复制
<ng-container routerLinkActive #rla="routerLinkActive" [routerLinkActiveOptions]="{exact: true}">
  <li [class.active]="rla.isActive || isActive">
    <a [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 || rla.isActive"
          *ngFor="let item of menuItem.children">
        <app-menu-item [menuItem]="item" (checkActive)="updateActiveState()"></app-menu-item>
      </ul>
    </ng-container>
  </li>

  <!--In case there is no link provided (has children)-->
  <ng-template #noLink>
    <li [class.active]="isActive">
      <a (click)="toggleActive()">
        <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>
    </li>
  </ng-template>
</ng-container>

这是我的组件

代码语言:javascript
复制
public menuSize;
  public isActive = false;

  @Input() menuItem: MenuItem;
  // @Input() routerActive: boolean;

  @ViewChild('rla') routerActive;

  @Output() checkActive: EventEmitter<void> = new EventEmitter<void>();
  @ViewChild(MenuItemComponent) menuComponent: MenuItemComponent;

  private hostActive = true;
  private hostActiveSm = false;

  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.router.events.subscribe((e: Event) => {
      if (e instanceof NavigationEnd) {
        this.updateActiveState();
      }
    });
  }

  ngOnChanges() {
  }

  ngAfterViewInit() {
    this.updateActiveState();
    console.log('This is active', this.routerActive);

    if (this.routerActive.isActive) {
      console.log('emitting');
      this.checkActive.emit();
    }
  }

  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;
    }

    if (this.menuComponent && this.menuComponent.isActive) {
      // console.log('Menu component');
      // console.log(this.menuComponent, this.menuComponent.menuItem.link);
      this.isActive = true;
    }
  }

问题是,当我通过控制台登录this.routerActive时,浏览器会打印出激活路由上带有isActive = true属性的routerLinkActive对象。

但是,如果我尝试通过控制台登录this.routerActive.isActive,它会打印出所有6个错误(就好像没有活动的路由一样)。

更新

为了更清楚起见,这里有更详细的日志

这就是我得到的

更新#2

刚尝试对一个对象赋值,得到6个isActive = false的对象

EN

回答 1

Stack Overflow用户

发布于 2018-11-15 21:17:15

如果您有几个类似的组件,则应该使用@ViewChild而不是@ViewChild,如下所示

代码语言:javascript
复制
@ViewChildren('rla')
routerActives: QueryList<RouterLinkActive>;

然后遍历它们以找到一个/达到期望的结果

代码语言:javascript
复制
this.routerActives.forEach((item) => {
...
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53320071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档