この記事では主に、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 = '李四'; //$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 = ''; $( 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
上記は、権威ある AngularJs チュートリアルからの文です。それはどういう意味ですか?$apply() 関数の役割は、Angular フレームワークの外側から Angular コンテキスト内で式を実行できます。
まず、ネイティブ JS またはサードパーティのフレームワーク (setTimeout や jquery プラグインなど) でモデルを変更しても、ビューの更新がトリガーされない可能性があることに注意する必要があります。なぜ?これらは Angularjs のコンテキストの外にあるため、Angularjs はデータの変更を監視できません。例を参照してください。
1.setTimeout
html:
$digest already in progress
js:
$timeout(function(){ $scope.name = '李四'; },500)
$scope.$apply()
を解放すると、Zhang San は正常に Li Si に変わります。 🎜🎜🎜2. サードパーティのプラグイン🎜🎜🎜html:🎜🎜🎜$scope.$evalAsync( function( $scope ) { console.log( "$evalAsync" ); } );
$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 サイトにご注意ください。 🎜🎜関連するおすすめ: 🎜
以上がAngularjs での $apply と最適化された使用についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。