dom完成渲染后,Angular2会执行操作

时间:2018-11-26 09:00:40

标签: javascript angular angular2-template

我的页面上有一个很大的ngx-bootstrap手风琴。当我打开一些较低的手风琴时,我希望它滚动页面,以便打开的手风琴从窗口顶部开始。我用scrollIntoView实现了滚动部分,但是现在的问题是在正确的时间执行它。我目前正在ngAfterViewChecked中执行此操作,但是多次触发了ViewChecked(mousemove,mouseenter等)。是否只有在DOM完成与angular2 + changeDetection分开的渲染之后才可以触发一段代码?

解决方案

这是开始起作用的解决方案。

constructor(elementRef: ElementRef) {
    this.elementRef = elementRef
  }

getData(){
   this.getService().then(result => {
      #do stuff with result
      setTimeout(() => this.scrollToBegin());
    }).catch((err: any) => {
    });
}

scrollToBegin(): any{
      this.elementRef.nativeElement.scrollIntoView();
    }

3 个答案:

答案 0 :(得分:1)

AFAIK,您只有ngAfterViewCheckedngAfterViewInit用于检测dom更新。

根据我的经验,有时您需要在settimeout内编写用于dom更改的代码,以便为此安排一个宏任务(异步更新),以便您的代码在下一个更改检测周期(即正是您所需要的)。有关更多详细信息,请参见this article

将您的罐子放在块代码末尾的settimeout内(并将其从ngAfterViewChecked中删除)。 一些例子:

setTimeout(() => htmlInputElement.focus()); // focus an input
setTimeout(() => htmlElement.scrollIntoView()); // scroll into view

答案 1 :(得分:0)

检查Angular文档中是否有不同的生命周期挂钩。初始化组件视图后,将调用生命周期挂钩。

AfterViewInit()将按照您的要求执行一次。

  

在Angular具有后立即调用的回调方法   完成组件视图的初始化。仅被调用   视图被实例化一次。

ngAfterVIewChecked()在加载组件的视图之后被调用,但是它检测到更改并执行。

答案 2 :(得分:0)

这是一个愚蠢的回应。但是您是否考虑过使用Accordeon随附的自定义事件isOpenChange

      <accordion-group heading="Group with isOpenChange event listener" 
(isOpenChange)="log($event)">
        <p>Some content</p>
      </accordion-group>

,然后在对应词中:

log(event: boolean) {
    console.log(`Accordion has been ${event ? 'opened' : 'closed'}`);
  }