web-dev-qa-db-ja.com

ngIf-チェック後に式が変更された

私は簡単なシナリオを持っていますが、うまく動かせません!

私の見解では、高さの制限されたボックスにテキストを表示します。

テキストはサーバーから取得されているため、テキストが入るとビューが更新されます。

これで、ボックス内のテキストがオーバーフローしている場合にボタンを表示するshouldngIfを持つ 'expand'ボタンがあります。

問題は、テキストがフェッチされると変更されるため、Angularの変更検出が終了すると、「展開」ボタンの状態がtrueに変わることです...

だから私はこのエラーを受け取ります:式はチェック後に変更されました。前の値: 'false'。現在の値: 'true'

明らかにボタンは表示されません...

こちらをご覧ください Plunker(コンソールでエラーを確認してください...)

これを機能させる方法はありますか?

21
naomi

このエラーは、dev mode

dev mode変更検出は、モデルが変更されたかどうかを確認するために、定期的な変更検出の実行ごとに追加のターンを追加します。

そのため、変更の検出を強制的に次のティックを実行するには、次のようなことができます。

export class App implements AfterViewChecked {

  show = false; // add one more property

  constructor(private cdRef : ChangeDetectorRef) { // add ChangeDetectorRef
    //...
  }
  //...
  ngAfterViewChecked() {
    let show = this.isShowExpand();
    if (show != this.show) { // check if it change, tell CD update view
      this.show = show;
      this.cdRef.detectChanges();
    }
  }

  isShowExpand()
  {
    //...
  }
}

ライブデモ: https://plnkr.co/edit/UDMNhnGt3Slg8g5yeSNO?p=preview

35
Tiep Phan

何らかの理由で、@ Tiep Phanの答えは変更検出を強制するために機能しませんでしたが、setTimeout(変更検出を強制する)を使用すると機能しました。

また、問題のある行に追加するだけで済み、ngAfterViewInitを追加する代わりに、ngOnInitに既にあるコードで正常に機能しました。

例:

ngOnInit() {
    setTimeout(() => this.loadingService.loading = true);
    asyncFunctionCall().then(res => {
        this.loadingService.loading = false;
    })
}

詳細はこちら: https://github.com/angular/angular/issues/6005

5
cs_pupil