如何确保 ngAfterViewInit 在呈现某个 HTML 元素后运行?

Posted

技术标签:

【中文标题】如何确保 ngAfterViewInit 在呈现某个 HTML 元素后运行?【英文标题】:How to make sure ngAfterViewInit runs after a certain HTML element is rendered? 【发布时间】:2022-01-21 20:09:14 【问题描述】:

html 中,有一个 <a> 重定向到另一个组件,然后滚动到某个锚点。

在目标组件中,我有以下代码

  ngAfterViewInit(): void 
    this.route.fragment.subscribe(fragment => 
      const elmntLoc: HTMLElement = document.getElementById(fragment);
      window.scroll(
        top: elmntLoc.offsetTop,
        behavior: "smooth"
      );
    );
  

但是我发现document.getElementById(fragment);总是null,因为这个元素是使用ngIf = booleanVariable有条件地显示的,而当这个ngAfterViewInit生命周期钩子运行时,这个booleanVariable还没有计算出来。

我想知道如何确保 ngAfterViewInit 在计算 booleanVariable 之后运行并因此呈现此元素?

我尝试使用setTime,但它看起来很老套...

提前致谢!

【问题讨论】:

您应该在计算booleanVariable 之后运行这段代码,而不是想要更改生命周期挂钩的行为。另外,请使用ViewChild,而不是直接在 Angular 中访问 DOM。 ***.com/questions/36101756/…的可能重复 【参考方案1】:

尝试改用 _elementRef:

this._elementRef.nativeElement.querySelector('#'+fragment)

【讨论】:

【参考方案2】:

您可以尝试等待下一个动画帧让 html 元素有机会呈现。

ngAfterViewInit(): void 
  this.route.fragment.subscribe(fragment => 
    window.requestAnimationFrame(_ => 
      const elmntLoc: HTMLElement = document.getElementById(fragment);
      window.scroll(
        top: elmntLoc.offsetTop,
        behavior: "smooth"
      );
    
  );

需要查看更多代码才能给出更可靠的答案。

【讨论】:

【参考方案3】:

感谢您的回答,但恐怕它们无法正常工作... (也许我以错误的方式尝试了它们。)

我设法解决了这个问题

  @ViewChild('elementId') set elementName(elementName: ElementRef) 
      # code to scroll to a certain section of the page.
  ;

该方法将在此ViewChild 呈现后运行。

【讨论】:

以上是关于如何确保 ngAfterViewInit 在呈现某个 HTML 元素后运行?的主要内容,如果未能解决你的问题,请参考以下文章

如何确保在 iOS 上的时限内呈现音频?

无法读取未定义的属性“nativeElement” - ngAfterViewInit

当 UIActivityViewController 呈现时,如何确保 UIActivityItemProvider 的项目准备就绪?

Rails - 如何确保已在 js.erb 中呈现部分内容

在 ngAfterViewinit 上推送未定义的数组

Angular2 ngAfterViewInit 啥时候被调用?