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

1974
Pashec 2012-03-14 00:16.

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

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

この作業を行う可能性のあるJavaScriptウォッチャーがあることがわかりました。ただし、Internet Explorer6およびInternetExplorer7ではサポートされていません。では、AngularJSは、たとえば次のように変更し、この変更をビューに反映したことをどのように認識しますか?

myobject.myproperty="new value";

14 answers

2751
Misko Hevery 2012-03-14 13:47.

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

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

ダーティチェック(AngularJS)と変更リスナー(KnockoutJSおよびBackbone.js)を対比するには:ダーティチェックは単純で非効率に見えるかもしれませんが(後で説明します)、常に意味的に正しいことがわかります。一方、変更リスナーには奇妙なコーナーケースがたくさんあり、セマンティックをより正確にするために依存関係の追跡などが必要です。KnockoutJSの依存関係の追跡は、AngularJSにはない問題に対する巧妙な機能です。

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

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

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

したがって、ダーティチェックは非効率的であるため、時間がかかるように見える場合があります。ここで、理論的な議論だけでなく実数を調べる必要がありますが、最初にいくつかの制約を定義しましょう。

人間は:

  • 遅い— 50ミリ秒より速いものは人間には知覚できないため、「インスタント」と見なすことができます。

  • 制限付き—1ページに約2000個を超える情報を人間に表示することはできません。それ以上のものは本当に悪いUIであり、人間はとにかくこれを処理することはできません。

だから本当の質問はこれです:あなたは50ミリ秒でブラウザ上でいくつの比較をすることができますか?多くの要因が関係してくるため、これは答えるのが難しい質問ですが、ここにテストケースがあります。http://jsperf.com/angularjs-digest/610,000人のウォッチャーが作成されます。最新のブラウザでは、これには6ミリ秒弱かかります。上のInternet Explorer 8には、約40ミリ秒かかります。ご覧のとおり、これは最近の遅いブラウザでも問題ではありません。注意点があります:比較は制限時間に収まるように単純である必要があります...残念ながら、遅い比較をAngularJSに追加するのは非常に簡単なので、自分が何であるかわからないときに遅いアプリケーションを簡単に構築できますやっている。しかし、どちらが遅い比較であるかを示すインストルメンテーションモジュールを提供することで答えが得られることを望んでいます。

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

325
MW. 2013-08-23 03:28.

Miskoは、データバインディングがどのように機能するかについてすでに優れた説明をしていますが、データバインディングのパフォーマンスの問題についての私の見解を追加したいと思います。

Miskoが述べたように、約2000のバインディングで問題が発生し始めますが、とにかく1ページに2000を超える情報を含めるべきではありません。これは真実かもしれませんが、すべてのデータバインディングがユーザーに表示されるわけではありません。双方向バインディングを使用してあらゆる種類のウィジェットまたはデータグリッドの構築を開始すると、UXが悪くなることなく、簡単に2000バインディングに到達できます

たとえば、テキストを入力して使用可能なオプションをフィルタリングできるコンボボックスについて考えてみます。この種のコントロールには最大150個のアイテムがあり、それでも非常に使いやすくなっています。追加機能がある場合(たとえば、現在選択されているオプションの特定のクラス)、オプションごとに3〜5個のバインディングを取得し始めます。これらのウィジェットのうち3つをページに配置すると(たとえば、1つは国を選択し、もう1つはその国の都市を選択し、3つ目はホテルを選択します)、すでに1000から2000の範囲のバインディングになっています。

または、企業のWebアプリケーションのデータグリッドを検討してください。1ページあたり50行は不合理ではなく、それぞれに10〜20列が含まれる可能性があります。これをng-repeatsで構築する場合、および/またはいくつかのバインディングを使用するいくつかのセルに情報がある場合、このグリッドだけで2000のバインディングに近づく可能性があります。

AngularJSを使用する場合、これは大きな問題であることがわかります。これまでに見つけた唯一の解決策は、ngOnceを使用する代わりに、双方向バインディングを使用せずにウィジェットを作成するか、ウォッチャーや同様のトリックを登録解除するか、 jQueryとDOM操作を使用してDOMを構築するディレクティブ。そもそもAngularを使うという目的に反しているように感じます。

これを処理する他の方法についての提案を聞きたいのですが、それなら私自身の質問を書くべきかもしれません。これをコメントに入れたかったのですが、長すぎて…

TL; DR
データバインディングは、複雑なページでパフォーマンスの問題を引き起こす可能性があります。

161
superluminary 2015-06-03 02:31.

$scopeオブジェクトをダーティチェックすることによって

Angulararrayは、$scopeオブジェクト内の単純なウォッチャーを維持します。いずれ$scopeかを調べると、array呼び出されたが含まれていることがわかります$$watchers

各ウォッチャーは、objectとりわけ含まれています

  1. ウォッチャーが監視している表現。これは単なるattribute名前か、もっと複雑なものかもしれません。
  2. 式の最後の既知の値。これは、式の現在の計算値に対してチェックできます。値が異なる場合、ウォッチャーは関数をトリガーし、$scopeをダーティとしてマークします。
  3. ウォッチャーが汚れている場合に実行される関数。

ウォッチャーの定義方法

AngularJSでウォッチャーを定義する方法はたくさんあります。

  • 明示的$watchattributeオンにすることができ$scopeます。

      $scope.$watch('person.username', validateUnique);
    
  • {{}}テンプレートに補間を配置できます(現在のウォッチャーが作成されます$scope)。

      <p>username: {{person.username}}</p>
    
  • ng-modelウォッチャーを定義するなどのディレクティブを要求できます。

      <input ng-model="person.username" />
    

$digestサイクルは、彼らの最後の値に対するすべてのウォッチャーをチェックします

通常のチャネル(ng-model、ng-repeatなど)を介してAngularJSと対話すると、ディレクティブによってダイジェストサイクルがトリガーされます。

ダイジェストサイクルは、そのすべての子の深さ優先探索$scopeです。それぞれについて$scope object、そのを繰り返し、$$watchers arrayすべての式を評価します。新しい式の値が最後の既知の値と異なる場合、ウォッチャーの関数が呼び出されます。この関数は、DOMの一部を再コンパイルし、の値を再計算し$scope、トリガーしAJAX request、必要なことは何でも行うことができます。

すべてのスコープがトラバースされ、すべてのウォッチ式が評価され、最後の値と照合されます。

ウォッチャーがトリガされた場合は、$scope汚れています

ウォッチャーがトリガーされると、アプリは何かが変更されたことを認識し、$scopeがダーティとしてマークされます。

ウォッチャー関数は$scope、親上または親上の他の属性を変更できます$scope。1つの$watcher関数がトリガーされた場合、他$scopeの関数がまだクリーンであるとは保証できないため、ダイジェストサイクル全体を再度実行します。

これは、AngularJSには双方向バインディングがあるため、データを$scopeツリーに戻すことができるためです。$scopeすでに消化されている高い方の値を変更する場合があります。おそらく、の値を変更します$rootScope

$digestが汚れている場合は、$digestサイクル全体を再度実行します

$digestダイジェストサイクルがクリーンになるまで(すべての$watch式の値が前のサイクルと同じになる)、またはダイジェスト制限に達するまで、サイクルを継続的にループします。デフォルトでは、この制限は10に設定されています。

ダイジェスト制限に達すると、AngularJSはコンソールでエラーを発生させます。

10 $digest() iterations reached. Aborting!

ダイジェストはマシンでは難しいですが、開発者にとっては簡単です

ご覧のとおり、AngularJSアプリで何かが変更されるたびに、AngularJSは$scope階層内のすべてのウォッチャーをチェックして応答方法を確認します。開発者にとって、これは生産性の大きな恩恵です。配線コードをほとんど記述する必要がないため、AngularJSは値が変更されたかどうかを認識し、アプリの残りの部分を変更と一致させます。

マシンの観点からは、これは非常に非効率的であり、ウォッチャーを作成しすぎるとアプリの速度が低下します。Miskoは、古いブラウザでアプリが遅く感じる前に、約4000人のウォッチャーの数字を引用しています。

この制限は、たとえばng-repeat大規模な場合に簡単に到達できますJSON array。ワンタイムバインディングなどの機能を使用して、ウォッチャーを作成せずにテンプレートをコンパイルすることで、これを軽減できます。

ウォッチャーが多すぎないようにする方法

ユーザーがアプリを操作するたびに、アプリ内のすべてのウォッチャーが少なくとも1回評価されます。AngularJSアプリを最適化することの大きな部分は、$scopeツリー内のウォッチャーの数を減らすことです。これを行う簡単な方法の1つは、1回のバインディングを使用することです。

めったに変更されないデータがある場合は、次のように::構文を使用して1回だけバインドできます。

<p>{{::person.username}}</p>

または

<p ng-bind="::person.username"></p>

バインディングは、含まれているテンプレートがレンダリングされ、データがにロードされたときにのみトリガーされ$scopeます。

これは、ng-repeatアイテムが多い場合に特に重要です。

<div ng-repeat="person in people track by username">
  {{::person.username}}
</div>
82
Pete BD 2012-03-14 11:01.

これが私の基本的な理解です。それは間違いかもしれません!

  1. アイテムは、関数(監視対象を返す)を$watchメソッドに渡すことによって監視されます。
  2. 監視対象アイテムへの変更は、$applyメソッドによってラップされたコードのブロック内で行う必要があります。
  3. 終わりに、彼らは最後の時間以降に変更かどうかを確認するために時計や小切手のそれぞれを通過され呼び出されるメソッド走りました。$apply$digest$digest
  4. 変更が見つかった場合は、すべての変更が安定するまでダイジェストが再度呼び出されます。

通常の開発では、HTMLのデータバインディング構文により、AngularJSコンパイラーにウォッチを作成するように指示され、コントローラーメソッドは$apply既に内部で実行されています。したがって、アプリケーション開発者にとっては、すべて透過的です。

63
jpsimons 2012-09-04 07:45.

私はしばらくこれを自分で疑問に思いました。セッターがいない場合AngularJS$scopeオブジェクトの変更にどのように気付くのですか?それらをポーリングしますか?

実際に行うことは次のとおりです。モデルを変更する「通常の」場所は、の内臓からすでに呼び出されてAngularJSいる$applyため、コードの実行後に自動的に呼び出されます。コントローラに、ng-clickある要素に接続されたメソッドがあるとします。AngularJSそのメソッドの呼び出しを一緒に配線するため$apply、適切な場所でを実行する機会があります。同様に、ビューに直接表示される式の場合、それらはによって実行されるAngularJSため、$apply

ドキュメント、の外部の$applyコードを手動で呼び出す必要があることについて説明している場合、実行時に呼び出しスタック内のコード自体に由来しないコードについて説明しています。AngularJSAngularJS

33
Nicolas Zozol 2016-05-21 03:33.

写真で説明する:

データバインディングにはマッピングが必要です

スコープ内の参照は、テンプレート内の参照とは異なります。2つのオブジェクトをデータバインドする場合、最初のオブジェクトをリッスンしてもう一方を変更する3番目のオブジェクトが必要です。

ここで、を変更するときは<input>data-ref3に触れます。そして、古典的なデータバインディングメカニズムはdata-ref4を変更します。では、他の{{data}}式はどのように動くのでしょうか?

イベントは$ digest()につながります

AngularはすべてのバインディングのoldValuenewValueを維持します。そして、Angularイベントが発生するたびに、有名な$digest()ループがWatchListをチェックして、何かが変更されたかどうかを確認します。これらの角度のイベントはあるng-clickng-change$http完成...$digest()限り、いずれかのような意志ループoldValueから異なりnewValue

前の図では、data-ref1とdata-ref2が変更されていることがわかります。

結論

卵と鶏肉に少し似ています。誰が開始するかはわかりませんが、ほとんどの場合、期待どおりに機能することを願っています。

もう1つのポイントは、単純なバインディングがメモリとCPUに与える影響を簡単に理解できることです。うまくいけば、デスクトップはこれを処理するのに十分太いです。携帯電話はそれほど強力ではありません。

22
Sasank Sunkavalli 2016-05-23 08:18.

明らかにScope、それに接続されているオブジェクトに変更があるかどうかの定期的なチェックはありません。スコープにアタッチされているすべてのオブジェクトが監視されるわけではありません。スコープは、典型的には$$ watchersを維持します。が呼び出された場合にScopeのみ、これを繰り返します。$$watchers$digest

Angularは、これらのそれぞれの$$ watchersにウォッチャーを追加します

  1. {{expression}} —テンプレート内(および式がある他の場所)またはng-modelを定義するとき。
  2. $scope.$watch( 'expression / function')— JavaScriptでは、Angularが監視するスコープオブジェクトをアタッチするだけです。

$ watch関数は、次の3つのパラメーターを取ります。

  1. 1つ目は、オブジェクトを返すだけのウォッチャー関数です。または、式を追加するだけです。

  2. 2つ目は、オブジェクトに変更があったときに呼び出されるリスナー関数です。DOMの変更などすべてがこの関数に実装されます。

  3. 3つ目は、ブール値を受け取るオプションのパラメーターです。真の場合、Angular Deepはオブジェクトを監視し、falseの場合、Angularはオブジェクトを参照監視します。$ watchの大まかな実装は次のようになります

Scope.prototype.$watch = function(watchFn, listenerFn) { var watcher = { watchFn: watchFn, listenerFn: listenerFn || function() { }, last: initWatchVal // initWatchVal is typically undefined }; this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers  
};

Angularにはダイジェストサイクルと呼ばれる興味深いものがあります。ザ・$digest cycle starts as a result of a call to $範囲。$digest(). Assume that you change a $ng-clickディレクティブを介したハンドラー関数のスコープモデル。その場合、AngularJSは自動的に$digest cycle by calling $ng-clickに加えて、モデルを変更できる他のいくつかの組み込みディレクティブ/サービスがあります(たとえば、ng-model、 $timeout, etc) and automatically trigger a $ダイジェストサイクル。$ digestの大まかな実装は次のようになります。

Scope.prototype.$digest = function() {
      var dirty;
      do {
          dirty = this.$$digestOnce(); } while (dirty); } Scope.prototype.$$digestOnce = function() {
   var self = this;
   var newValue, oldValue, dirty;
   _.forEach(this.$$watchers, function(watcher) {
          newValue = watcher.watchFn(self);
          oldValue = watcher.last;   // It just remembers the last value for dirty checking
          if (newValue !== oldValue) { //Dirty checking of References 
   // For Deep checking the object , code of Value     
   // based checking of Object should be implemented here
             watcher.last = newValue;
             watcher.listenerFn(newValue,
                  (oldValue === initWatchVal ? newValue : oldValue),
                   self);
          dirty = true;
          }
     });
   return dirty;
 };

JavaScriptのsetTimeout()関数を使用してスコープモデルを更新する場合、Angularには何を変更する可能性があるかを知る方法がありません。この場合、$ apply()を手動で呼び出すのは私たちの責任です。これにより、$digest cycle. Similarly, if you have a directive that sets up a DOM event listener and changes some models inside the handler function, you need to call $apply()を使用して、変更を確実に有効にします。の大きなアイデア$apply is that we can execute some code that isn't aware of Angular, that code may still change things on the scope. If we wrap that code in $適用、それは呼び出しの世話をします $digest(). Rough implementation of $apply()。

Scope.prototype.$apply = function(expr) { try { return this.$eval(expr); //Evaluating code in the context of Scope
       } finally {
         this.$digest();
       }
};
16
Bharath Kumar 2016-05-17 05:05.

AngularJSは、$ watch()、$ digest()、$ apply()の3つの強力な関数を使用してデータバインディングメカニズムを処理します。ほとんどの場合、AngularJSは$ scopeを呼び出します。$watch() and $scope。$ digest()ですが、場合によっては、これらの関数を手動で呼び出して、新しい値で更新する必要があります。

$ watch():-

この関数は、$ scopeの変数の変化を監視するために使用されます。これは、式、リスナー、および等価オブジェクトの3つのパラメーターを受け入れます。ここで、リスナーと等価オブジェクトはオプションのパラメーターです。

$ digest() -

この関数は、内のすべての時計を繰り返し処理します $scope object, and its child $スコープオブジェクト
(存在する場合)。いつ$digest() iterates over the watches, it checks if the value of the expression has changed. If the value has changed, AngularJS calls the listener with new value and old value. The $AngularJSが必要と判断した場合はいつでもdigest()関数が呼び出されます。たとえば、ボタンをクリックした後、またはAJAX呼び出しの後。AngularJSが$ digest()関数を呼び出さない場合があります。その場合、あなたはそれを自分で呼ぶ必要があります。

$ apply() -

Angularは、AngularJSコンテキスト内にあるモデルの変更のみを自動的に魔法のように更新します。Angularコンテキスト外のモデル(ブラウザーのDOMイベント、setTimeout、XHR、サードパーティライブラリなど)で変更を行う場合は、を呼び出して変更をAngularに通知する必要があります。$apply() manually. When the $apply()関数呼び出しはAngularJS呼び出しを内部的に終了するため、すべてのデータバインディングが更新されます。

7
gartox 2013-09-18 19:57.

たまたま、人のデータモデルをフォームにリンクする必要がありました。私が行ったのは、データをフォームに直接マッピングすることでした。

たとえば、モデルに次のようなものがある場合:

$scope.model.people.name

フォームの制御入力:

<input type="text" name="namePeople" model="model.people.name">

そうすれば、オブジェクトコントローラの値を変更すると、これがビューに自動的に反映されます。

私がモデルを渡した例は、サーバーデータから更新されます。郵便番号を要求し、そのビューに関連付けられたコロニーと都市のリストをロードし、デフォルトでユーザーに最初の値を設定します。そして、これは私が非常にうまく機能しました、何が起こるかというとangularJS、モデルを更新するのに数秒かかることがあります。これを行うには、データを表示しながらスピナーを配置できます。

6
Shankar Gangadhar 2017-06-18 09:28.
  1. 一方向のデータバインディングは、値がデータモデルから取得され、HTML要素に挿入されるアプローチです。ビューからモデルを更新する方法はありません。これは、従来のテンプレートシステムで使用されます。これらのシステムは、データを一方向にのみバインドします。

  2. Angularアプリのデータバインディングは、モデルコンポーネントとビューコンポーネント間のデータの自動同期です。

データバインディングを使用すると、モデルをアプリケーションの信頼できる唯一の情報源として扱うことができます。ビューは常にモデルの投影です。モデルが変更された場合、ビューは変更を反映し、その逆も同様です。

5
AllJs 2016-04-07 08:15.

これは、入力フィールドを使用したAngularJSとのデータバインディングの例です。後で説明します

HTMLコード

<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
     <input type="text" ng-model="watchInput" Placeholder="type something"/>
     <p>{{watchInput}}</p> 
</div>

AngularJSコード

myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
  //Your Controller code goes here
}]);

上記の例でわかるように、AngularJSng-model、HTML要素、特にinputフィールドで何が起こるかをリッスンして監視するために使用します。何かが起こったら、何かをしなさい。私たちの場合、ng-modelは口ひげ表記を使用して、私たちのビューにバインドされています{{}}。入力フィールド内に入力されたものはすべて、画面に即座に表示されます。これが、AngularJSを最も単純な形式で使用するデータバインディングの美しさです。

お役に立てれば。

Codepenで実際の例をご覧ください

5
ojus kulkarni 2016-09-02 21:35.

AngularJsは双方向のデータバインディングをサポートしています。
データにアクセスできることを意味します[表示]-> [コントローラーコントローラー]-> [表示]

例の場合

1)

// If $scope have some value in Controller. $scope.name = "Peter";

// HTML
<div> {{ name }} </div>

O / P

Peter

ng-modelLikeでデータをバインドできます:
-2)

<input ng-model="name" />

<div> {{ name }} </div>

上記の例では、ユーザーが入力するものは何でも、<div>タグで表示されます。

HTMLからコントローラーに入力をバインドする場合:
-3)

<form name="myForm" ng-submit="registration()">
   <label> Name </lbel>
   <input ng-model="name" />
</form>

ここnameで、コントローラーの入力を使用する場合は、

$scope.name = {}; $scope.registration = function() {
   console.log("You will get the name here ", $scope.name);
};

ng-modelビューをバインドし、式でレンダリングします{{ }}
ng-modelビューでユーザーに表示され、ユーザーが操作するデータです。
そのため、AngularJsでデータをバインドするのは簡単です。

4
Shankar Gangadhar 2016-10-31 13:20.

Angular.jsは、ビューで作成するすべてのモデルのウォッチャーを作成します。モデルが変更されるたびに、「ng-dirty」クラスがモデルに追加されるため、ウォッチャーは、クラス「ng-dirty」を持つすべてのモデルを監視し、コントローラーで値を更新します。その逆も同様です。

3
Dhana 2018-07-06 01:38.

データバインディング:

データバインディングとは何ですか?

ユーザーがビュー内のデータを変更するたびに、スコープモデルでその変更の更新が発生します。その逆も同様です。

どうしてそれは可能ですか?

短い答え:ダイジェストサイクルの助けを借りて。

説明: Angular jsは、スコープモデルにウォッチャーを設定します。スコープモデルは、モデルに変更があった場合にリスナー関数を起動します。

$scope.$watch('modelVar' , function(newValue,oldValue){

//新しい値でコードを更新します

});

では、ウォッチャー関数はいつどのように呼び出されますか?

ウォッチャー関数は、ダイジェストサイクルの一部として呼び出されます。

ダイジェストサイクルは、ng-model、ng-bind、$ timeout、ng-clickなどのAngular js組み込みディレクティブ/サービスの一部として自動的にトリガーされ、ダイジェストサイクルをトリガーできます。

ダイジェストサイクル機能:

$scope.$digest() -> digest cycle against the current scope. $scope.$apply() -> digest cycle against the parent scope 

すなわち$rootScope.$apply()

注:$ apply()は $rootScope.$ダイジェスト()これは、ダーティチェックがルートまたはトップまたは親スコープからAngularjsアプリケーションのすべての子$ scopeまで開始されることを意味します。

上記の機能は、アプリケーションがAngular jsアプリケーションであることを確認するだけで、前述のバージョンのブラウザーIEでも機能します。つまり、scriptタグで参照されているangularjsフレームワークスクリプトファイルを使用しています。

ありがとうございました。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

グッドジョブ、ESPN

グッドジョブ、ESPN

今日のホワイトハウスの記者会見で、報道官のサラ・ハッカビー・サンダースは、スポーツセンターのホストであるイェメル・ヒルのドナルド・トランプに関する最近のツイートについてコメントするよう求められ、大統領と彼の政策を白人至上主義者として説明した。ヒルは彼女のつぶやきのためにESPNによって公に叱責されました。

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

基本的に頭のあらゆる部分から髪の毛を整えたり、ブロードライしたり、まっすぐにしたり、脱毛したりする必要がある場合は、このレミントンゴールドボックスが最適です。今日だけ、Amazonは、すでに人気のあるShortcut Pro Self-HaircutKitやPearlPro Ceramic Flat Ironのように、グルーミングをはるかに簡単にするヘアツールをマークダウンしています。

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

トゥパックシャクール(ティムモーゼンフェルダー/ゲッティイメージズ); マヤアンジェロウ(マーティンゴッドウィン/ゲッティイメージズ)移動、テイラースウィフト。ケンドールとカイリーは、必要な数の座席を持っています。

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

写真:Tesla Motorsフロリダに住んでいて、Tesla Model S、Model X 60、またはModel 60Dを使用している場合、車の自律性は50 km(約30マイル)高くなります。これは失敗ではなく、ハリケーンイルマによる避難作業を容易にするために会社自身が命じた自治権の一時的な延長です。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language