【问题标题】:Which lifecycle hook to edit dom in Angular2在Angular2中编辑dom的生命周期钩子
【发布时间】:2017-10-02 12:01:05
【问题描述】:

我有一个非常基本的 angular2 Web 应用程序。我想知道可以添加代码以编辑 DOM 的正确位置/挂钩。

当我尝试将其放入 ngAfterViewInit 时,我看到以下错误

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. 

我发现让它工作的唯一方法是像这样在超时中包装我的代码

setTimeout(_ => {
   .... code comes here ...
})

这似乎不是正确的方法。有什么想法吗?

组件 JS 代码

export class LandingPageComponent implements OnInit {

  techImageSize = "100"

  constructor() { }

  ngOnInit() {
  }

  ngAfterViewInit(){
    setTimeout(_ => {
      var w = $("[data-container=tech-images]").width();
      this.techImageSize = Math.floor(w / 4) + "";
    })
  }

}

相关模板代码:

<div class="col-md-5" data-container="tech-images">
  <div class="" style='overflow: auto'>
    <tech-image image='heroku-logo.png' [size]="techImageSize"></tech-image>
    <tech-image image='surge-logo.svg' [size]="techImageSize"></tech-image>
    <tech-image image='swift-logo.png' [size]="techImageSize"></tech-image>
    <tech-image image='heroku-logo.png' [size]="techImageSize"></tech-image>
  </div>
</div>

【问题讨论】:

  • 你的代码是...?
  • @smnbbrv 我更新了帖子,谢谢!
  • 我们也能看到你的组件模板 HTML 吗?至少对于相关的data-container="tech-images" 元素。我猜它的一个维度被设置为this.techImageSize,但这是在更改检测周期中发生的。
  • 现在就来看看吧 :)
  • @PrakashRaman,JackKoppa 很好地解释了为什么你会收到这个错误,这就是为什么 setTimeout 是必要的——以避免弄乱更改检测。除此之外,请注意在 Angular 中强烈建议不要对 DOM 进行任何直接操作(尤其是使用 jQuery)。

标签: angular


【解决方案1】:

这是预期的行为。我假设您在组件模板中使用techImageSizengAfterViewInit 生命周期钩子在检查 DOM 后触发。然后将其更新为

this.techImageSize = Math.floor(w / 4) + "";

所以在下一个验证阶段,Angular 会检测到 techImageSize 值的差异并抛出错误。

根据组件的模板,您可能需要等待ngAfterViewInit 生命周期挂钩,在这种情况下,通过超时使用异步更新是正确的方法。但是,通常,您可以在任何钩子中访问 DOM,因为当更改检测开始并触发钩子时,DOM 已经呈现。

您可以阅读更多内容:

【讨论】:

  • 我明白了,谢谢。通读帖子。在这种情况下,什么时候是更新 DOM 的合适时间。或者如何在它被检查之前更新它?
  • @PrakashRaman,我更新了答案。查看以Depending...开头的段落
猜你喜欢
  • 2018-03-13
  • 2016-08-26
  • 2017-12-06
  • 2015-12-08
  • 2017-07-12
  • 2017-01-02
  • 2017-02-20
  • 2020-01-15
  • 2017-11-22
相关资源
最近更新 更多