[解決済み】markForCheck()とdetectChanges()の違いは何ですか?)
質問
とはどのような違いがあるのでしょうか?
ChangeDetectorRef.markForCheck()
と
ChangeDetectorRef.detectChanges()
?
自分だけ
SOに関する情報が見つかりました。
との違いについて
NgZone.run()
この2つの関数の間にはありません。
ドキュメントを参照しただけの回答の場合、どちらかを選択するための実際のシナリオを説明してください。
どのように解決するのですか?
<ブロッククオートdetectChanges() : void
つまり、モデル(クラス)内部が変更されてもビューに反映されていない場合、Angularに通知してその変更を検出(ローカルの変更を検出)し、ビューを更新する必要があるかもしれないのです。
考えられるシナリオは以下の通りです。
1- 変更検出器がビューから切り離されている ( デタッチ )
2- 更新が行われましたが、Angular Zoneの中に入っていないため、Angularはそれについて知りません。
例えば、サードパーティーの関数がモデルを更新し、その後にビューを更新したい場合などです。
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
このコードはAngularの圏外にあるため(おそらく)、変更を検知してビューを更新することを確認する必要がある可能性が最も高いです。
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
ノート :
言い換えれば、Angularの変更サイクルの中にその変更を取り込む他の方法があります。
** サードパーティーの関数をzone.runでラップすることができます。
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** この関数は setTimeout 内でラップすることができます。
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
3- また、モデルを更新した後に
change detection cycle
が終了した場合、この恐ろしいエラーが発生します。
チェックした後に式が変更されました"。
これは一般的に(Angular2言語から):
私はあなたのモデルで、私が受け入れた方法(イベント、XHRリクエスト、setTimeout、...)の1つによって引き起こされた変更を見ました。そして、あなたのビューを更新するために変更検出を実行し、それを完了しました。
このエラーには必ず出くわします :P .
それを修正するためのいくつかの方法。
1- 正しい方法 : 更新が変更検出サイクルの内側であることを確認してください (Angular2 の更新は一度だけ起こる一方向の流れです。その後モデルを更新せず、より良い場所/時間にコードを移動してください)。
2- 怠惰な方法 これは間違いなく最良の方法ではありませんが、可能なシナリオは何かと聞かれたので、そのうちの1つを紹介します。
この方法は、「あなたが変更検知を実行したことは心から知っているが、あなたがチェックを終えた後、私はその場で何かを更新しなければならなかったので、もう一度実行してほしい」と言いたいのです。
3- コードを
setTimeout
というのも
setTimeout
はゾーンによってパッチが適用され
detectChanges
が終了した後に
ドキュメントより
markForCheck() : void
これは主に 変更検出ストラテジー である場合、そのコンポーネントは オンプッシュ .
OnPush自体は、これらのいずれかが発生した場合にのみ、変更検知を実行することを意味します。
1- コンポーネントの@Inputの1つが完全に新しい値で置き換えられた場合、または簡単に言えば、@Inputプロパティの参照が完全に変更された場合です。
ですから、もし 変更検出ストラテジー である場合、そのコンポーネントは オンプッシュ そして、あなたは、:
var obj = {
name:'Milad'
};
そして、それを更新/変異させるのです。
obj.name = "a new name";
を更新しません。 オブジェ を参照するため、変更検出は実行されず、したがってビューには更新/変異が反映されません。
この場合、手動でAngularにビューをチェックし更新するように指示する必要があります(markForCheck)。
だから、あなたがこれをした場合。
obj.name = "a new name";
する必要があります。
this.cd.markForCheck();
むしろ、以下のようにすると、変更検出が実行されることになります。
obj = {
name:"a new name"
};
これは、以前の obj を完全に置き換えて、新しい
{}
;
2- クリックなどのイベントが発生したか、子コンポーネントのいずれかがイベントを発信しました。
のようなイベント。
- クリック
- キー操作
- サブスクリプションイベント
- その他
要するに:
-
使用方法
detectChanges()
は、angularが変更検知を実行した後にモデルを更新した場合、もしくは更新がangular worldに全く反映されていない場合です。 -
使用方法
markForCheck()
OnPush を使っていて、かつChangeDetectionStrategy
の内部でモデルを更新した場合、データを変異させるか、あるいは セットタイムアウト ;
関連
-
[解決済み] Angular 2でディレイを作成する方法
-
[解決済み] CLIでコンポーネントを削除する最も良い方法は何ですか?
-
[解決済み] Angular 2の「コンポーネント」は既知の要素ではありません。
-
[解決済み] コンストラクタとngOnInitの違いについて
-
[解決済み] NgModuleにおける宣言、プロバイダ、インポートの違いは何ですか?
-
[解決済み】PromiseとObservablesの違いは何ですか?
-
[解決済み】Angular2 Exception: routerLink'が既知のネイティブプロパティではないため、バインドできない。
-
[解決済み】@ViewChildと@ContentChildの違いは何ですか?
-
[解決済み] Angular2の括弧、括弧、アスタリスクの違いは何ですか?
-
[解決済み] テンプレート駆動型とリアクティブ型の実用的な違いとは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】angularでpreflightのレスポンスがHTTP okステータスにならない。
-
[解決済み] LegendItemComponent をカスタマイズする Angular 用 kendo-ui
-
[解決済み] Angular 5:"ControlContainerのプロバイダがありません"
-
[解決済み] AngularのmatSortがソートされない
-
[解決済み] CLIでコンポーネントを削除する最も良い方法は何ですか?
-
[解決済み] プロパティ 'json' はタイプ 'Object' に存在しません。
-
[解決済み] switchの使用時に「ステートメントはif文でフィルタリングされなければならない」というtslintのクレームが発生する。
-
[解決済み] Angular2において、テンプレートを必要としないコンポーネントがありますが、テンプレートエラーが発生します。
-
[解決済み] Angularで電話番号の入力をフォーマットする
-
[解決済み] モジュール 'AppModule' によってインポートされた予期しないディレクティブ 'LoginComponent' があります。NgModuleアノテーションを追加してください。