ホームページ >ウェブフロントエンド >jsチュートリアル >Angularjs での $apply と最適化された使用について

Angularjs での $apply と最適化された使用について

不言
不言オリジナル
2018-07-02 13:59:101621ブラウズ

この記事では主に、Angularjs での $apply の最適化された使用方法について詳しく紹介します。必要な方は一緒に参照してください。

前書き

フロントエンドの全くの初心者である私にとって、JavaScript についてはまだ少しは知っていますが、Angular JS を直接使い始めようとすると、多くの抵抗に遭遇します。しかし、私は努力さえすれば、たとえ反人類的なデザインであっても大きな問題にはならないと信じています。

今日は、Angularjs の小さな星 $apply について話します。データが更新されてもビュー層が応答しないときは、apply を使用してくださいという声が常に聞こえます。その後、無知なので、割り当てコードの最後に $scope.$apply() を追加します。 . code> 、そして私はそれを知って嬉しい驚きを感じました。おお、本当に更新されました。 <p></p> <p>しかし、場合によっては、コンパイラーが容赦なく <code>$scope.$apply() ,然后就惊喜的发现。噢,真的更新了。

然而,有些时候,编译器会无情的给你返回

Error: $digest already in progress

那么,导致这些现象的原因时什么的呢?$apply究竟干了啥?听我慢慢到来。

一.$apply的作用

$apply()函数可以从Angular框架的外部让表达式在Angular上下文内部执行。

上面是AngularJs权威教程中的一句话。什么意思呢?

首先,你要清楚,在原生js或者第三方框架下,修改model,是有可能不会触发视图更新的,比如setTimeout、jquery插件。为什么?因为他们脱离了Angularjs的上下文,Angularjs并不能监听到数据的改变。看例子。

1.setTimeout

html:

<p>{{name}}</p>

js:

$scope.name="张三";
setTimeout(function(){
$scope.name = &#39;李四&#39;;
//$scope.$apply()
},500)

首先,name等于张三,500ms后,我把他赋值为李四,但是,页面上并没有改变,依然是张三。

而,我们把$scope.$apply()放开,就正常了,张三成功变为李四。

2.第三方插件

html:

<p>Date: <input type="text" id="datepicker"></p>
<p>
<header>所选日期</header>
{{selectedDate}}
</p>

js:

$scope.selectedDate = &#39;&#39;;
$( function() {
 $( "#datepicker" ).datepicker({
 onClose: function( selectedDate ) {
 $scope.selectedDate = selectedDate;
 // $scope.$apply();
 }
 });
} );

这是jquery的datepicker插件,当我们选定日期后,下面的日期应该随之显现,而现在却没有。这种情况就必须依靠$apply(),才能更新视图。

以上两种情况,都因为不处于Angularjs上下文中,导致监听不到数据的变化。而$apply究竟干了什么,才导致数据更新正常了呢?

其实$apply相当于一个触发器,它的作用就是触发digest循环,从而更新视图。

在digest是Angularjs的核心,是它实现了神奇的数据绑定。凡是触发事件,必会触发digest循环,比如,我们数值的ng事件,click啊,change,实际上都是触发了digest循环。

所以,我们所做的事,其实就是手动触发了digest循环。关于digest循环,属于题外话,这里不做过多介绍,想深入了解的同学,可以看看书籍,或者百度。

二.更好地运用digest循环

在Angularjs中,除了$apply可以触发digest循环外,还有其他的方法,也可以触发此循环。而且$apply往往时最坏的选择。下面推荐一些更好的选择。

1.$digest

$scope.$digest()

Error: $digest selected are in progress

というメッセージを返すことがあります。では、これらの現象の原因は何でしょうか? $apply は具体的に何をするのでしょうか?ゆっくり来るのを聞いてください。

1. $apply

$apply() 関数の役割は、Angular フレームワークの外側から Angular コンテキスト内で式を実行できます。

上記は、権威ある AngularJs チュートリアルからの文です。それはどういう意味ですか?

まず、ネイティブ JS またはサードパーティのフレームワーク (setTimeout や jquery プラグインなど) でモデルを変更しても、ビューの更新がトリガーされない可能性があることに注意する必要があります。なぜ?これらは Angularjs のコンテキストの外にあるため、Angularjs はデータの変更を監視できません。例を参照してください。

1.setTimeout

html:

$digest already in progress

js:

$timeout(function(){
$scope.name = &#39;李四&#39;;
},500)

まず、500ms後に彼をLi Siに割り当てましたが、ページは変わりません。何も変わっていません。Zhang San のままです。

🎜しかし、$scope.$apply() を解放すると、Zhang San は正常に Li Si に変わります。 🎜🎜🎜2. サードパーティのプラグイン🎜🎜🎜html:🎜🎜🎜
$scope.$evalAsync(
   function( $scope ) {
   console.log( "$evalAsync" );
   }
  );
🎜🎜🎜js:🎜🎜🎜rrreee🎜🎜🎜 日付を選択すると、次の日付が表示されます。が表示されますが、今はありません。この場合、ビューを更新するには $apply() に依存する必要があります。 🎜🎜上記 2 つのケースでは、Angularjs コンテキスト内にないため、データの変更を監視できません。そして、データが正常に更新されるようにするために $apply は正確に何をしたのでしょうか? 🎜🎜🎜実際、$apply はトリガーに相当し、その機能はビューを更新するダイジェスト ループをトリガーすることです。 🎜🎜🎜 Digest は Angularjs の中核であり、魔法のようなデータ バインディングを実装します。トリガーされるイベントは必ずダイジェスト サイクルをトリガーします。たとえば、数値イベントであるクリックと変更は、実際にダイジェスト サイクルをトリガーします。 🎜🎜そこで、私たちが行ったのは、実際にダイジェスト サイクルを手動でトリガーすることでした。ダイジェストサイクルについては余談ですが、詳しく知りたい学生は書籍や百度を読んでください。 🎜🎜🎜🎜2. ダイジェストループのより良い使用法🎜🎜🎜🎜 Angularjs では、ダイジェストループをトリガーできる $apply に加えて、このループをトリガーできる他のメソッドもあります。そして $apply は多くの場合最悪の選択です。いくつかのより良いオプションを以下に推奨します。 🎜🎜🎜1.$digest🎜🎜🎜$scope.$digest() は、親スコープの現在のスコープと子スコープの値のみを更新するため、$apply よりも高速です時間に関係なく。また、$apply は親スコープも評価する必要があるため、パフォーマンスが大幅に消費されます。 🎜🎜🎜2.$timeout🎜🎜🎜$timeout を使用して setTimeout を置き換えます。$timeout は Angularjs の組み込みサービスであり、もちろん Angularjs 環境により適しています。暗黙的にダイジェスト ループをトリガーし、前のダイジェスト ループが完了した次の瞬間にダイジェスト ループをトリガーするため、上記の 🎜🎜🎜rrreee🎜🎜🎜 が発生しません。 setTime $timeout にコードを入れてください🎜🎜🎜rrreee🎜🎜🎜 これで正常に動作します。面倒な適用はありません。 🎜🎜🎜3.$evalAsync🎜🎜🎜この方法が最も推奨されます。現在実行中のダイジェスト サイクルがある場合は、ダイジェスト サイクルを引き起こした操作を現在のダイジェスト サイクルに入れて実行します。 $timeout は、現在のダイジェスト サイクルが完了するまで待機してから、ダイジェスト サイクルを再度実行します。したがって、evalAsync はより高速に実行され、パフォーマンスが向上します。 $timeout のように呼び出すことができます。つまり、 🎜🎜🎜rrreee🎜🎜🎜 以上が今日言いたいことのすべてです。 Angularjs にはまだまだ多くの秘密やより良い使用法が隠されていますので、それらを深く研究し、より良い記事を共有していただければ幸いです。 🎜🎜🎜以下は実行可能コードです。探索できます: https://codepen.io/hanwolfxue/pen/yEZbYQ🎜🎜 上記はこの記事の全内容です。学習に役立つことを願っています。その他の関連コンテンツ PHP 中国語 Web サイトにご注意ください。 🎜🎜関連するおすすめ: 🎜

Angular4の組み込み命令の基本的な使い方について

angularJsでブラウザのキャッシュをクリアする方法

以上がAngularjs での $apply と最適化された使用についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。