简体   繁体   English

Angular ngAfterViewInit() 找不到 DOM 元素

[英]Angular ngAfterViewInit() not finding DOM element

I am trying to target a menu item element in my navigation that has an active class in order to do some custom animations.我正在尝试定位导航中具有活动 class 的菜单项元素,以便执行一些自定义动画。

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

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

This returns null when I am expecting something like <a class="active">Home</a> .当我期待像<a class="active">Home</a>这样的东西时,这会返回null However if I wrap the querySelector in a setTimeout function I get the correct result.但是,如果我将 querySelector 包装在 setTimeout function 中,我会得到正确的结果。

This made me think ngAfterViewInit() was firing before the router was finished its events.这让我认为ngAfterViewInit()在路由器完成其事件之前触发。

I wrote a function to subscribe to the router events however it has the same result我写了一个 function 来订阅路由器事件,但是它具有相同的结果

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

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

This will also return null but if I wrap this in a setTimeout as well if works.这也将返回 null 但如果我将它包装在 setTimeout 中,如果有效。

My links look like this我的链接看起来像这样

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

I am just trying to get the DOM element of the link with the active class at the end of some sort of lifecycle method or observable event.我只是想在某种生命周期方法或可观察事件结束时获取具有活动 class 的链接的 DOM 元素。 Am I missing something or am I stuck with setTimeouts and race conditions?我是否遗漏了什么,或者我被 setTimeouts 和比赛条件困住了?

Try to set static:false :尝试设置static:false

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

As Angular docs says: 正如 Angular 文档所说:

In the official API docs, we have always recommended retrieving query results in ngAfterViewInit for view queries and ngAfterContentInit for content queries.在官方 API 文档中,我们一直建议在ngAfterViewInit中检索视图查询和ngAfterContentInit中的内容查询。 This is because by the time those lifecycle hooks run, change detection has completed for the relevant nodes and we can guarantee that we have collected all the possible query results.这是因为当这些生命周期钩子运行时,相关节点的更改检测已经完成,我们可以保证我们已经收集了所有可能的查询结果。 Most applications will want to use {static: false} for the same reason.出于同样的原因,大多数应用程序都希望使用{static: false} This setting will ensure query matches that are dependent on binding resolution (eg results inside *ngIfs or *ngFor's ) will be found by the query.此设置将确保查询可以找到依赖于绑定解析的查询匹配(例如*ngIfs*ngFor's中的结果)。

You are missing #container on the element:您在元素上缺少#container

<a class="link" [routerLink]="['/home']" routerLinkActive="active" #container>Home</a>

#container references the element with @ViewChild() . #container使用@ViewChild()引用元素。 The @ViewChild() decorator queries for the element using the selector which is container in your case. @ViewChild()装饰器使用在您的情况下是container的选择器查询元素。

Edit for the updated question:编辑更新的问题:

For getting the children elements use ElementRef<HTMLElement>;要获取子元素,请使用ElementRef<HTMLElement>; :

@ViewChild('container', { static: true }) container: ElementRef<HTMLElement>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM