使用setTimeout时,Angular4 ngAfterViewChecked多次调用

时间:2018-01-22 12:42:14

标签: angular

我有一个服务,我想在视图完全呈现后调用。我做了一些挖掘并找到了Angular生命周期。对我来说,最好的方法似乎是AfterViewChecked,所以我更新了我的 AppComponent 并添加了:

import { Component, OnInit, AfterViewChecked } from "@angular/core";
import { ActivatedRoute, Params } from "@angular/router";

import { ResultsService } from "./shared/results.service";
import { HeightService } from "./shared/height.service";

@Component({
  selector: 'bzRoot',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, AfterViewChecked {

  constructor(
    private _activatedRoute: ActivatedRoute,
    private _resultsService: ResultsService,
    private _heightService: HeightService
  ) { }

  ngOnInit() {
    this._activatedRoute.queryParams.subscribe((params: Params) => this._resultsService.elq = params['elq']);
  }

  ngAfterViewChecked() {
    console.log('hi');
  }
}

当我运行我的应用程序时,我可以看到控制台有25个实例" hi"在里面。我不知道为什么会这么多,但这不是问题所在。 我的方法是调用我创建的服务,该服务使用postMessage向父窗口发送消息。它看起来像这样:

import { Injectable } from '@angular/core';

@Injectable()
export class HeightService {

  constructor() { }

  public resize() {
    console.log('resizing');

    var body = document.body,
        html = document.documentElement;

    var height = Math.max( 
      body.scrollHeight, 
      body.offsetHeight, 
      body.clientHeight, 
      html.offsetHeight
    );

    setTimeout(function () {
      parent.postMessage(height, '*');
    }, 0);
  }
}

我的ngAfterViewChecked方法现在看起来像这样:

ngAfterViewChecked() {
  this._heightService.resize();
}

如果我注释掉setTimeout行,则会返回到25个调用。 有谁知道为什么以及如何阻止它发生?

1 个答案:

答案 0 :(得分:1)

这是设计的。 docs说:

  

ngAfterViewChecked()
  在Angular检查组件的视图和子视图后进行响应。   在ngAfterViewInit和随后的每个ngAfterContentChecked()之后调用。   仅限组件的挂钩。

您正在寻找ngAfterViewInit()挂钩

编辑:似乎角钩不是您需要的解决方案,您应该保存发送的最后一个高度值,并且仅在值更改时触发调整大小

react-native-fetch-polyfill