【问题标题】:Angular2 do actions after dom has finished renderingdom完成渲染后Angular2执行操作
【发布时间】:2019-04-27 21:25:31
【问题描述】:

我在页面上有一个大型 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();
    }

【问题讨论】:

  • ngOnInit 钩子有什么问题。在显示所有绑定后触发它。更重要的是,它会被触发一次。
  • 但是每次打开手风琴时我都需要触发它。当我打开页面时,所有 ngOnInits 都已完成。之后不再调用它。

标签: javascript angular angular2-template


【解决方案1】:

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

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

在 Angular 完成后立即调用的回调方法 完成了组件视图的初始化。它只被调用 视图实例化时一次。

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

【讨论】:

    【解决方案2】:

    AFAIK 你只有 ngAfterViewCheckedngAfterViewInit 来检测 dom 更新。

    根据我的经验,有时您需要在 settimeout 中编写用于 dom 更改的代码,以便为此安排宏任务(异步更新),以便您的代码将在下一个更改检测周期中运行(这正是你需要)。更多详情见this article

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

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

    【讨论】:

    • 当我把它放在 afterViewChecked 里面时它没有工作。但是,如果我将它作为 AJAX 所做的最后一件事添加,它就开始起作用了。
    • @MarkoTaht 你做对了。我编辑了我的答案以澄清这一点。
    【解决方案3】:

    这是一个愚蠢的回应。但是您是否考虑过使用随手风琴提供的自定义事件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'}`);
      }
    

    【讨论】:

    • 我已经在使用它了。 isOpenChange 调用从服务器获取数据的 ajax 调用。我尝试在 ajax 结束时调用 scrollIntoView 事件,但它不起作用,因为它现在正在执行 DOM 更新。
    • 好的。所以这是一个时间问题。你调用了 http 端点并且你想在调用返回时执行一些操作?
    • 来自端点的数据创建一个大表。因此,如果手风琴是列表中的最后一个,您需要手动滚动才能查看内容,如果它会自动在列表中居中会很好。 vmoh_ir 的答案是我正在寻找的解决方案。
    • 这不是解决方案,而是解决方法。调用 set timeout 是实现您想要的非确定性方式。我想找到一个真正的解决方案。因为我将来可能会遇到这个问题。
    • 您能否发布完整的解决方案。现在编写的代码。
    猜你喜欢
    • 2016-04-17
    • 2018-04-05
    • 2017-10-30
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2018-06-27
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多