[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
質問
でのデータバインディングはどのように機能するのでしょうか?
AngularJS
フレームワーク
の技術的な詳細がわからないのですが。 サイト . ビューからモデルへデータが伝搬されるときの動作は、だいたいわかっています。しかし、AngularJSはセッターやゲッターなしで、どのようにモデルプロパティの変更を追跡するのでしょうか?
があることを発見しました。 JavaScript ウォッチャー この作業を行うことができるかもしれません。しかし、それらは インターネットエクスプローラー6 と インターネットエクスプローラー7 . では、AngularJSは私が例えば次のように変更して、この変更をビューに反映させたことをどのように知るのでしょうか?
myobject.myproperty="new value";
解決方法は?
AngularJSは値を記憶し、以前の値と比較します。これは基本的なダーティチェックです。もし値に変化があれば、changeイベントを発生させます。
は
$apply()
メソッドは、非AngularJSの世界からAngularJSの世界へ移行するときに呼び出されるものであり、このメソッドでは
$digest()
. ダイジェストとは、単なる古いダーティチェックのことです。すべてのブラウザーで動作し、完全に予測可能です。
ダーティチェック(AngularJS)とチェンジリスナー( ノックアウトJS と バックボーン.js ): ダーティチェックは単純で非効率的に見えるかもしれませんが(これについては後で触れます)、意味的に常に正しいことがわかります。一方、チェンジリスナーには奇妙なコーナーケースがたくさんあり、より意味的に正しくするために依存関係追跡のようなものが必要です。KnockoutJSの依存性トラッキングは、AngularJSにはない問題に対する賢い機能です。
チェンジリスナーに関する問題点。
- ブラウザがネイティブにサポートしていないため、構文が非道い。確かにプロキシはありますが、すべてのケースで意味的に正しいわけではありませんし、もちろん古いブラウザではプロキシはありません。要するに、ダーティチェックによって POJO KnockoutJSやBackbone.jsでは、クラスを継承し、アクセッサを通してデータにアクセスすることを強制されます。
- 合体を変更する。アイテムの配列があるとします。配列にアイテムを追加したい場合、addをループしていると、addするたびにchangeのイベントが発生し、UIがレンダリングされます。これはパフォーマンス的に非常に悪い。UIを更新したいのは、最後に一度だけです。changeイベントは細かすぎるのです。
- 変更リスナーはセッターですぐに起動します。これは問題で、変更リスナーがさらにデータを変更すると、さらに変更イベントが発生するからです。これは、スタック上で一度に複数の変更イベントが発生する可能性があるため、好ましくないことです。例えば、何らかの理由で同期が必要な2つの配列があるとします。どちらか一方にしか追加できませんが、追加するたびに change イベントが発生し、その結果、世界の見え方がおかしくなってしまいます。これはスレッドロックと非常によく似た問題で、JavaScript では各コールバックが排他的かつ完結に実行されるため、これを回避することができます。変更イベントはこれを打ち破ります。なぜなら、セッターは意図しない、あるいは明白でない結果を広範囲に及ぼす可能性があり、スレッドの問題が繰り返されるからです。つまり、リスナーの実行を遅延させ、一度に1つのリスナーのみが実行され、どのコードも自由にデータを変更でき、その間に他のコードが実行されないことを保証することが必要なのです。
パフォーマンスについてはどうですか?
つまり、ダーティチェックは非効率なので、遅く見えるかもしれません。ここは机上の空論ではなく、実際の数字を見ていく必要がありますが、まずは制約を定義してみましょう。
人間は
-
スロー - 50ミリ秒より速いものは、人間には感知できないので、インスタントとみなすことができます。
-
限定 - 1ページで約2000以上の情報を人間に見せることはできないのです。それ以上はUIが悪くなりますし、人間はこれを処理することはできません。
そこで、本当の問題はこれです。ブラウザ上で50msの間にいくつの比較ができるのか?これは多くの要素が絡んでくるので、答えにくい質問ですが、テストケースを紹介します。 http://jsperf.com/angularjs-digest/6 で、10,000のウォッチャーを作成します。モダンなブラウザでは、この処理に6ミリ秒弱かかります。また インターネットエクスプローラー8 は、約40ミリ秒かかります。このように、最近の遅いブラウザでも問題ないことがわかります。注意点としては、比較対象がシンプルでないと制限時間に収まらないということです...。残念ながら、AngularJSに遅い比較を追加するのはあまりにも簡単なので、何をやっているのかわからないと遅いアプリケーションを作るのは簡単なのです。しかし、私たちはインスツルメンテーションモジュールを提供することで、どれが遅い比較なのかがわかるような答えを出したいと思っています。
ビデオゲームやGPUがダーティチェック方式を採用しているのは、特に一貫性があるからだと判明しました。モニターのリフレッシュレート(通常50~60Hz、または16.6~20ms毎)を超える限り、それ以上のパフォーマンスは無駄なので、FPSを高くするよりも、より多くのものを描画する方がよいのです。
関連
-
要素ツリー制御によるvueTreeテーブル
-
[解決済み】Node.js Error: Cannot find module express
-
[解決済み】React - TypeError: 未定義のプロパティ 'props' を読み取ることができない。
-
[解決済み】ReactJSでエラー発生 Uncaught TypeError: Super expression は null か関数でなければならず、undefined ではありません。
-
nullのプロパティinnerHTMLを読み取れません エラーメッセージ
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
JSアレイループと効率解析の比較
-
JavaScriptにおけるマクロタスクとミクロタスクの詳細
-
vueにおけるv-forループオブジェクトのプロパティ
-
[解決済み] Error : 未定義のプロパティ 'map' を読み取ることができません。
-
[解決済み】awaitは非同期関数でのみ有効です。
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】ExpressJS - throw er Unhandled errorイベント
-
[解決済み】React-Redux: アクションはプレーンオブジェクトでなければならない。非同期アクションにはカスタムミドルウェアを使用する
-
[解決済み] オブザーバー、Pub/Sub、データバインディングの違いについて
-
[解決済み] AngularJS vs Angular【クローズド】。