3

HTML要素を別のコンポーネントの相対位置に配置しようとしているコンポーネントを含むAngular 2アプリを作成しました。正確な座標を計算するには、ブラウザーによってレンダリングされる独自の要素の幅と高さを知る必要があります。

私はwindow.getComputedStyle(this.elementRef.nativeElement)それらのプロパティを取得するために使用しています。ページがレンダリングされると、ページのレンダリングが完了するまでプロパティが変化し続けることに気付きました。変更について通知を受けて配置を調整するためngAfterViewCheckedに、コンポーネントのメソッドで値を確認します。

ただし、計算されたスタイルのプロパティがまだ変更されているにもかかわらず、私のフックがもう呼び出されていないことがわかったため、レンダリングが新しい計算されたスタイルのプロパティにつながるときは呼び出されないngAfterViewCheckedようです。Angular フレームワークは、そのような変更を検出するようには設計されていないと思います。

私の最初の試みはngDoCheckフックを実装することでしたが、これはしばらくしてから計算されたスタイル プロパティが最終的な値になる前に呼び出されないようです。このフックが呼び出される正確なタイミングをまだ完全には理解していないと思います。

setTimeoutで関数を実装するngAfterViewCheckedと、次のようなダミー関数のみを渡したとしても、同じフックが後で再度呼び出されることにつながることが最終的にわかりました。

setTimeout(() => {}, 500);

しかし、率直に言って、なぜそうなるのか理解できません。フックの関係を誰か説明してくれませんか?setTimeoutngAfterViewChecked

そして、これはやや汚い回避策ですが、計算されたスタイル属性の変更を検出して処理する適切な「Angular」の方法は何ですか?


コードの抜粋:

export class MyComponent implements OnInit, AfterViewChecked
{
  private cssWidth: number;
  private cssHeight: number;

  constructor(private elementRef: ElementRef, private renderer: Renderer2)
  {
  }

  ngAfterViewChecked()
  {
    console.log("ngAfterViewChecked");
    this.updateView();
  }

  public updateView()
  {
    const sizeX = parseFloat(window.getComputedStyle(this.elementRef.nativeElement).width) || 0;
    const sizeY = parseFloat(window.getComputedStyle(this.elementRef.nativeElement.height) || 0;

    if (sizeX === this.cssWidth && sizeY === this.cssHeight) {
      // no change
      return;
    }

    console.log("Change detected!");

    // TODO Does not work without this dummy timeout function (else no more changes detected) - why so??
    setTimeout(() => {}, 500);

    [.. doing the positioning here ..]
 }
4

3 に答える 3