1. ホーム
  2. typescript

[解決済み] チェックした後に○○の表現が変わっている

2022-03-27 11:34:42

質問

なぜ、このシンプルな ポロンポロン

@Component({
  selector: 'my-app',
  template: `<div>I'm {{message}} </div>`,
})
export class App {
  message:string = 'loading :(';

  ngAfterViewInit() {
    this.updateMessage();
  }

  updateMessage(){
    this.message = 'all done loading :)'
  }
}

を投げる。

EXCEPTION: 式 'I'm {{message}} in App@0:5' はチェックされた後、変更されました。前の値:'読み込み中 :( '. 現在の値:'読み込みはすべて終了しました :) ' in [I'm {{message}} in App@0:5].

ビューが開始されたときに、単純なバインディングを更新しているだけなのに?

どのように解決するのですか?

まず、この例外が発生するのは、アプリを開発モードで実行しているときだけであることに注意してください(beta-0 のデフォルトでは、このようになっています)。もし enableProdMode() がスローされることはありません ( 更新されたplunkを見る ).

2つ目 やめとけ つまり、開発モードの場合、変更検出の各ラウンドの直後に、最初のラウンドの終了後にバインディングが変更されていないことを確認するための2ラウンド目が行われます。

あなたのplunkでは、バインディングの {{message}} を呼び出すことで変更されます。 setMessage() で発生します。 ngAfterViewInit フック、これは最初の変更検出ターンの一部として発生します。しかし、それ自体は問題ではありません。 setMessage() バインディングを変更しても、新しい変更検出のラウンドは始まらないので、将来どこかで変更検出のラウンドが始まらないと、この変更は検出されないことを意味します。

持ち味は。 バインディングを変更するものはすべて、変更検出のラウンドをトリガーする必要があります。 を実行したとき。

すべての要望に応えて更新し、その例を紹介する : の3つのメソッドと同様に、@Tychoのソリューションは動作します。 回答 MarkRajcok さんのご指摘の通りです。しかし、率直に言って、それらはすべて醜く、間違っているように感じます。

確かに 時折 これらのハックが適切な状況ではありますが、もしあなたが とても それは、フレームワークのリアクティブな性質を完全に受け入れるのではなく、むしろフレームワークと戦っている証拠です。

IMHOは、このアプローチのより慣用的な、"Angular2方法"は、ラインに沿って何かをすることです。( ポトン )

@Component({
  selector: 'my-app',
  template: `<div>I'm {{message | async}} </div>`
})
export class App {
  message:Subject<string> = new BehaviorSubject('loading :(');

  ngAfterViewInit() {
    this.message.next('all done loading :)')
  }
}