フロントエンドの純粋な初心者である私にとって、JavaScriptはまだそれについて少し明確です。 Angular JSを直接始めたい場合は、本当に多くの抵抗があります。しかし、私はあなたが一生懸命働く限り、反人間のデザインでさえ大きな問題ではないと信じています。
さて、あまりナンセンスを言わないでください。 Angular JSとは何かを把握するために、私はスコープから始めました。では、スコープとは何ですか?公式文書からの通路を借りる:
コードコピーは次のとおりです。
「スコープは、アプリケーションモデルを指すオブジェクトです。これは式の実行コンテキストです。スコープは、アプリケーションのDOM構造を模倣する階層構造に配置されています。スコープは式を見てイベントを伝播できます。」
それを読んだ後、私はそれを他のプログラミング言語と比較し、範囲はデータモデルの範囲のようなものであり、表現の実行のコンテキストを提供すると感じました。とりあえずこのように理解しましょう。
スコープの特徴
次に、範囲がどのような機能を持っているか見てみましょう。
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');
関数ButtonClicked(){
アラート( 'ボタンがクリックされた');
}
button.addeventlistener( 'click'、buttonclicked);
function timercomplete(){
Alert( 'Timer Complete');
}
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が行うことです(以前は触れたことはありませんが)。別の方法は、Angular JSによって採用された方法です。これは、各JavaScriptコード実行シーケンスが実行された後にデータ変更があるかどうかをチェックします。これは効率的ではないようであり、パフォーマンスに深刻な影響を与えることさえあります。ただし、Angular JSは、この問題を解決するためにいくつかの賢い手段を使用しています(まだ研究されていませんが、まだ明確ではありません)。これを行うことの利点は、任意のオブジェクトを自由に使用できること、割り当て方法に制限がないこと、およびデータの変更を認識できることです。
Angular JSが採用したこのソリューションでは、データが変更されることを気にします。そこでScope.Apply()が役立ちます。バウンドデータが変更されたかどうかを確認すると、実際にはscope.digest()によって行われますが、このメソッドを直接呼び出すことはほとんどありませんが、scope.apply()メソッドではscope.digest()メソッドを呼び出すため、scope.apply()メソッドと呼ばれます。 scope.apply()メソッドは関数または式を実行してから実行し、最後にscope.digest()メソッドを呼び出して、バインディングまたはウォッチャーを更新します。
$ apply()を使用するタイミング
同じ質問は、いつapply()メソッドを呼び出す必要があるのですか?ケースはほとんどありません。実際、コードのほぼすべてがscope.apply()に巻き付けられています。これは、ngクリック、コントローラーの初期化、httpコールバック関数などです。これらの場合、自分自身を呼び出す必要はありません。コードを新しい実行シーケンスで実行する必要がある場合は、実際に使用する必要があります。新しい実行シーケンスがAngular JSライブラリメソッドによって作成されていない場合にのみ、scope.apply()でコードをラップする必要があります。説明する例は次のとおりです。
コードコピーは次のとおりです。
<div ng:app ng-controller = "ctrl"> {{message}} </div>
コードコピーは次のとおりです。
functionctrl($ scope){
$ scope.message = "更新のために2000msを待っている";
setimeout(function(){
$ scope.message = "Timeout Call!";
// angularjs $スコープへの更新を認識していません
}、2000);
}
上記のコードが実行された後、ページが表示されます:2000ミリ秒待っている更新を待っています。明らかに、データの更新はAngular JSによって検出されませんでした。
次に、JavaScriptコードをわずかに変更し、scope.apply()でラップします。
コードコピーは次のとおりです。
functionctrl($ scope){
$ scope.message = "更新のために2000msを待っている";
setimeout(function(){
$ scope。$ apply(function(){
$ scope.message = "Timeout Call!";
});
}、2000);
}
今回の違いは、ページが最初に表示されることです。アップデートを2000ミリ秒待っています。 2秒間待った後、コンテンツは次のように変更されます:Timeout Call! 。明らかに、データの更新は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()メソッドは、Angular Frameworkの外でAngular JS式を実行できます。これはほんの始まりに過ぎません。水はまだ深く、一緒に深く潜ることができます!