Angular2 在 dom 完成渲染后执行操作

Angular2 do actions after dom has finished rendering

我在页面上有一个很大的 ngx-bootstrap 手风琴。当我打开一些较低的手风琴时,我希望它滚动页面,以便打开的手风琴从 window 的顶部开始。我用 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();
    }

查看 Angular 不同生命周期钩子的文档。组件视图初始化后调用生命周期挂钩。

AfterViewInit() 将根据您的要求执行一次。

A callback method that is invoked immediately after Angular has completed initialization of a component's view. It is invoked only once when the view is instantiated.

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

据我所知,您只有 ngAfterViewCheckedngAfterViewInit 用于检测 dom 更新。

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

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

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

这是一个愚蠢的回应。但是你有没有考虑使用手风琴附带的自定义事件 isOpenChange:

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

然后在 copponent:

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