AngularJS でデータバインディングはどのように機能しますか? 質問する

AngularJS でデータバインディングはどのように機能しますか? 質問する

フレームワークではデータ バインディングはどのように機能しますかAngularJS?

技術的な詳細は見つかりませんでした彼らのサイトデータがビューからモデルに伝播されるときにどのように動作するかは、多かれ少なかれ明らかです。しかし、AngularJS はセッターとゲッターなしでモデル プロパティの変更をどのように追跡するのでしょうか?

私は、JavaScriptウォッチャーこの作業を実行できる可能性があります。ただし、サポートされていませんインターネットエクスプローラー6そしてインターネットエクスプローラー7では、AngularJS はどのようにして、たとえば次のように変更したことを認識し、この変更をビューに反映するのでしょうか?

myobject.myproperty="new value";

ベストアンサー1

AngularJS は値を記憶し、それを以前の値と比較します。これは基本的なダーティチェックです。値に変更があった場合は、変更イベントが発生します。

メソッド$apply()は、AngularJS 以外の世界から AngularJS の世界に移行するときに呼び出すもので、 を呼び出します$digest()。ダイジェストは、単純な古いダーティ チェックです。すべてのブラウザーで動作し、完全に予測可能です。

ダーティチェック(AngularJS)と変更リスナー(ノックアウトJSそしてバックボーン): ダーティチェックは単純に見え、非効率的でさえあるかもしれませんが (これについては後で説明します)、実際には意味的には常に正しいことがわかります。一方、変更リスナーには奇妙なコーナーケースがたくさんあり、意味的に正しくするためには依存関係の追跡などが必要になります。KnockoutJS の依存関係の追跡は、AngularJS にはない問題に対する巧妙な機能です。

変更リスナーに関する問題:

  • ブラウザがネイティブにサポートしていないため、構文はひどいです。確かにプロキシはありますが、すべてのケースで意味的に正しいわけではなく、もちろん古いブラウザにはプロキシはありません。要するに、ダーティチェックにより、ポジョ一方、KnockoutJS と Backbone.js では、クラスを継承し、アクセサーを介してデータにアクセスする必要があります。
  • 変更の結合。アイテムの配列があるとします。配列にアイテムを追加したいとします。追加するためにループしているため、追加するたびに変更のイベントが発生し、UI がレンダリングされます。これはパフォーマンスに非常に悪影響を及ぼします。必要なのは、最後に 1 回だけ UI を更新することです。変更イベントは細分化されすぎています。
  • 変更リスナーはセッターに対してすぐに起動しますが、これは問題です。変更リスナーはデータをさらに変更できるため、より多くの変更イベントが起動されるからです。スタック上で複数の変更イベントが同時に発生する可能性があるため、これはよくありません。何らかの理由で同期を維持する必要がある 2 つの配列があるとします。どちらか一方にしか追加できませんが、追加するたびに変更イベントが起動され、ワー​​ルド ビューが不一致になります。これはスレッド ロックと非常によく似た問題です。JavaScript では、各コールバックが排他的に完了まで実行されるため、スレッド ロックは回避されます。変更イベントは、セッターが意図せず明らかでない広範囲にわたる結果をもたらす可能性があるため、この問題に違反し、スレッドの問題が再び発生します。必要なのは、リスナーの実行を遅らせ、一度に 1 つのリスナーだけが実行されるように保証することです。そのため、どのコードでもデータを自由に変更でき、変更中は他のコードが実行されないことがわかります。

パフォーマンスはどうですか?

ダーティチェックが非効率なので、遅いように見えるかもしれません。ここでは、理論的な議論だけでなく、実数を見る必要がありますが、まずはいくつかの制約を定義しましょう。

人間とは:

  • 低速— 50 ミリ秒より速いものは人間には知覚できないため、「瞬時」とみなすことができます。

  • 制限あり— 1 ページで人間に表示できる情報は 2000 個程度までです。それ以上になると UI が悪くなり、人間はこれを処理できません。

本当の質問は、ブラウザで 50 ミリ秒以内に何回比較できるかということです。多くの要因が関係するため、この質問に答えるのは難しいですが、テストケースを以下に示します。http://jsperf.com/angularjs-digest/610,000人のウォッチャーを作成します。最新のブラウザでは、これはわずか6ミリ秒未満です。インターネットエクスプローラー8約 40 ミリ秒かかります。ご覧のとおり、最近の低速ブラウザでもこれは問題になりません。ただし、注意点があります。時間制限内に収めるには、比較をシンプルにする必要があります... 残念ながら、AngularJS に低速の比較を追加するのは非常に簡単なので、何をしているのかわからないと、低速のアプリケーションを簡単に構築できます。ただし、どの比較が低速であるかを示すインストルメンテーション モジュールを提供することで、この問題を解決したいと考えています。

ビデオ ゲームと GPU では、一貫性があるためにダーティ チェック アプローチが使用されています。モニターのリフレッシュ レート (通常は 50 ~ 60 Hz、または 16.6 ~ 20 ミリ秒ごと) を超えると、それを超えるパフォーマンスは無駄になるため、FPS を上げるよりも、より多くのものを描画する方が効果的です。

おすすめ記事