我试图在导航中定位具有活动类的菜单项元素,以便执行一些自定义动画。

export class NavComponent implements AfterViewInit {
    @ViewChild('container', { static: true }) container: ElementRef

    ngAfterViewInit() {
        const activeEl = this.container.nativeElement.querySelector('.active')
        console.log(activeEl)
    }
}


当我期望像null这样的东西时,它将返回<a class="active">Home</a>。但是,如果将querySelector包装在setTimeout函数中,则会得到正确的结果。

这使我认为ngAfterViewInit()在路由器完成其事件之前就在触发。

我编写了一个函数来订阅路由器事件,但是结果相同

constructor(private route: Router) {
    this.routeEvent(this.route)
}

routeEvent(router: Router) {
    router.events.subscribe(e => {
        if (e instanceof NavigationEnd) {
            this.container.nativeElement.querySelector('.active')
        }
    })
}


这也将返回null,但是如果可以的话,我也将其包装在setTimeout中。

我的链接看起来像这样

<nav #container>
    <a class="link" [routerLink]="['/link1']" routerLinkActive="active">Link1</a>
    <a class="link" [routerLink]="['/link2']" routerLinkActive="active">Link2</a>
    <a class="link" [routerLink]="['/link3']" routerLinkActive="active">Link3</a>
    <a class="link" [routerLink]="['/link4']" routerLinkActive="active">Link4</a>
</nav>


我只是想在某种生命周期方法或可观察事件的结尾获取与活动类的链接的DOM元素。我是否缺少某些东西,或者我陷入了setTimeouts和竞争条件的困境?

最佳答案

尝试设置static:false

@ViewChild('container', { static: false }) container: ElementRef


As Angular docs says:


  在官方API文档中,我们始终建议检索查询
  导致ngAfterViewInit用于视图查询,而ngAfterContentInit用于
  内容查询。这是因为到了那些生命周期的钩子
  运行,相关节点的更改检测已完成,我们可以
  确保我们已经收集了所有可能的查询结果。
  大多数应用程序都希望使用{static: false}相同
  原因。此设置将确保查询匹配项取决于
  绑定分辨率(例如*ngIfs*ngFor's内的结果)将为
  由查询找到。

09-18 00:40