ホームページ  >  記事  >  ウェブフロントエンド  >  angularJS_AngularJS の $apply() メソッドの詳細な説明

angularJS_AngularJS の $apply() メソッドの詳細な説明

WBOY
WBOYオリジナル
2016-05-16 16:21:461184ブラウズ

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

さて、これ以上ナンセンスはやめてください。 Angular JS とは何かを理解するために、Scope から始めました。では、スコープとは何でしょうか?公式文書から一節を借用:

コードをコピーします コードは次のとおりです:

「スコープはアプリケーション モデルを参照するオブジェクトです。これは式の実行コンテキストです。スコープはアプリケーションの DOM 構造を模倣する階層構造で配置されます。スコープは式を監視し、イベントを伝播できます。」

これを読んだ後、他のプログラミング言語に例えると、スコープはデータ モデルのスコープのようなもので、式の実行にコンテキストを提供するものだと感じました。今はこのように理解しましょう。

スコープの特徴

次に、Scope にはどのような機能があるのか​​見てみましょう。

Scope は、モデルの変更を監視するための $watch メソッドを提供します。
Scope は、モデルの変更を伝播するための $apply メソッドを提供します。
スコープを継承して、さまざまなアプリケーション コンポーネントとプロパティのアクセス許可を分離できます。
スコープは、式の評価のコンテキストを提供します。

この 4 つの機能について、私は ActionScript、C、Java を勉強したことがあるので、1 つ目、3 つ目、4 つ目は理解するのが難しくありませんが、2 つ目の点が少しわかりにくい気がします。答えを求めるという原則に従い、Google を通じていくつかの情報を見つけました。経験豊富なベテランの方は、レンガをタップしてください。

オリジン Javascript

まず、scope.apply() は一見すると、バインディングを更新するための普通のメソッドのように見えます。しかし、もう少し考えてみましょう。なぜそれが必要なのでしょうか?通常いつ使用されますか?これら 2 つの問題を理解するには、JavaScript から始める必要があります。 Javascript コードでは、コード フラグメントが実行される順番になると、ブラウザは現在のフラグメントのみを実行し、他には何も実行しません。そのため、あまりよくできていない Web ページでは、何かをクリックした後に停止してしまうことがあります。これは、JavaScript の動作方法がこの現象の原因の 1 つです。以下にそれを感じるためのコードを示します:

コードをコピーします コードは次のとおりです:

var button = document.getElementById('clickMe');
機能ボタンをクリックしました () {
alert('ボタンがクリックされました');
}
button.addEventListener('click', buttonClicked);
function timerComplete () {
alert('タイマー完了');
}
setTimeout(timerComplete, 5000);

Javascript コードをロードするときは、まず「clickMe」という ID を持つボタンを見つけて、次にリスナーを追加し、次にタイムアウトを設定します。 5 秒ほど待つと、ダイアログ ボックスが表示されます。ページを更新してすぐに clickMe ボタンをクリックすると、ダイアログ ボックスが表示されます。OK をクリックしないと、timerComplete 関数は実行されません。

バインディングを更新する方法

さて、一見関係のない話をした後、本題に戻りましょう。 Angular JS はデータが変更され、ページを更新する必要があることをどのようにして知るのでしょうか?コードはデータがいつ変更されたかを知る必要がありますが、現時点ではオブジェクト上のデータが変更されたことを直接通知する方法はありません (ECMAScript 5 はこの問題を解決しようとしていますが、まだ実験段階です)。現在主流となっている戦略には、次の 2 つのソリューションがあります。 1 つは、特別なオブジェクトを使用して、すべてのデータをプロパティを通じて直接指定するのではなく、オブジェクトのメソッドを呼び出すことによってのみ設定できるようにする方法です。このようにして、すべての変更を記録できるため、ページをいつ更新する必要があるかがわかります。この欠点は、特別なオブジェクトを継承しなければならないことです。割り当ては、object.key=value ではなく object.set('key', 'value') を通じてのみ行うことができます。 EmberJS や KnockoutJS などのフレームワークではこれを行います (ただし、私はこれにさらされたことがありません。恥ずかしいことです)。もう 1 つは、Angular JS で採用されている方法で、JavaScript コードの実行シーケンスごとにデータの変更があるかどうかをチェックします。これは非効率的であり、パフォーマンスに重大な影響を与える可能性もあります。ただし、Angular JS はこの問題を解決するためにいくつかの賢い方法を使用します (まだ研究されておらず、明確ではありません)。この利点は、任意のオブジェクトを自由に使用でき、代入方法に制限がなく、データの変更も検出できることです。
Angular JS で採用されているこのソリューションでは、データがいつ変更されるかが重要であり、ここでscope.apply() が役に立ちます。バインドされたデータが変更されたかどうかのチェックは、実際にはscope.digest()によって行われますが、このメソッドを直接呼び出すことはほとんどありませんが、scope.apply()メソッドのスコープ内で、スコープ.ダイジェスト()メソッド。 scope.apply() メソッドは関数または式を取得して実行し、最後にscope.digest() メソッドを呼び出してバインディングまたはウォッチャーを更新します。

$apply() を使用する場合

同じ質問ですが、いつ apply() メソッドを呼び出す必要があるのでしょうか?実際、ng-click、コントローラーの初期化、http コールバック関数など、ほとんどすべてのコードがscope.apply() でラップされている状況は非常にまれです。このような場合、自分で呼び出す必要はありません。実際、自分で呼び出すことはできません。そうしないと、 apply() メソッド内で apply() メソッドを呼び出すとエラーがスローされます。新しい実行シーケンスでコードを実行する必要がある場合、およびこの新しい実行シーケンスが Angular JS ライブラリ メソッドによって作成されない場合にのみ、これを使用する必要があります。現時点では、コードのスコープを使用する必要があります。 apply() がラップされました。例を使って説明しましょう:

コードをコピーします コードは次のとおりです:

{{メッセージ}}

コードをコピーします コードは次のとおりです:

functionCtrl($scope) {
$scope.message ="更新まで 2000 ミリ秒待っています"; setTimeout(function() {
$scope.message="タイムアウトが発生しました!";
// AngularJS は $scope
への更新を認識しません }、2000);
}

上記のコードが実行されると、ページに「更新を 2000 ミリ秒待機しています」と表示されます。どうやらデータの更新はangular JSによって認識されないようです。

次に、JavaScript コードを少し変更し、scope.apply() でラップします。

コードをコピーします コードは次のとおりです:
functionCtrl($scope) {
$scope.message ="更新まで 2000 ミリ秒待っています"; setTimeout(function() {
$scope.$apply(function() {
$scope.message="タイムアウトが発生しました!";
});
}、2000);
}

今回の違いは、ページに最初に「更新を 2000 ミリ秒待機しています」と表示され、2 秒待った後、コンテンツが「タイムアウトが呼び出されました!」に変更されることです。明らかに、データの更新は angular JS によって認識されます。
注: これを行うべきではありませんが、angular JS によって提供されるタイムアウト メソッドを使用して、apply メソッドで自動的にラップされるようにします。

科学は諸刃の剣です
最後に、scope.apply() メソッドとscope.apply(function) メソッドをもう一度見てみましょう。 angular JS は私たちに多くのことをもたらしてくれましたが、いくつかの機会も失いました。以下の疑似コードから一目でわかります:

コードをコピーします コードは次のとおりです:

function$apply(expr) {
{
を試してください return$eval(expr);
} catch(e) {
$ExceptionHandler(e);
} ついに {
$root.$digest();
}
}

すべての例外をキャッチし、再度スローしません。最後に、$digest() メソッドが呼び出されます。

要約すると

$apply() メソッドは、DOM イベント、setTimeout、XHR、またはその他のサードパーティ ライブラリなど、Angular フレームワークの外側で Angular JS 式を実行できます。これはほんの始まりにすぎません。水はまだ非常に深いです。皆さんも一緒に深く潜ってください。

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