誰か簡単な言葉で説明できますか?
ドキュメントは少し鈍いようです。どちらをいつ使用するかの本質と全体像がわかりません。この 2 つを対比する例は素晴らしいでしょう。
誰か簡単な言葉で説明できますか?
ドキュメントは少し鈍いようです。どちらをいつ使用するかの本質と全体像がわかりません。この 2 つを対比する例は素晴らしいでしょう。
compile 関数 -テンプレートDOM 操作 (つまり、tElement = テンプレート要素の操作) に使用します。したがって、ディレクティブに関連付けられたテンプレートのすべての DOM クローンに適用される操作です。
リンク関数 - DOM リスナー (つまり、インスタンス スコープでの $watch 式) およびインスタンスDOM 操作 (つまり、iElement = 個々のインスタンス要素の操作) の登録に使用します。
テンプレートが複製された後に実行されます。たとえば、<li ng-repeat...> 内では、特定の <li> 要素の <li> テンプレート (tElement) が (iElement に) 複製された後に、リンク関数が実行されます。
$watch() を使用すると、インスタンス スコープ プロパティの変更をディレクティブに通知できます (インスタンス スコープは各インスタンスに関連付けられます)。これにより、ディレクティブは更新されたインスタンス値を DOM にレンダリングできます -- インスタンス スコープのコンテンツをDOM。
DOM 変換は、コンパイル関数および/またはリンク関数で実行できることに注意してください。
ほとんどのディレクティブは特定の DOM 要素インスタンス (およびそのインスタンス スコープ) のみを処理するため、ほとんどのディレクティブはリンク関数のみを必要とします。
scope
どちらを使用するかを決定するのに役立つ 1 つの方法: コンパイル関数が引数を受け取らないことを考慮して ください。(トランスクルードされたスコープを受け取るトランスクルード リンク関数の引数を意図的に無視しています。これはめったに使用されません。) したがって、コンパイル関数は、(インスタンス) スコープを必要とする、やりたいことは何もできません。モデル/インスタンス スコープ プロパティを $watch しない、インスタンス スコープ情報を使用して DOM を操作できない、インスタンス スコープで定義された関数を呼び出せない、など。
ただし、コンパイル機能 (リンク機能など) は属性にアクセスできます。したがって、DOM 操作にインスタンス スコープが必要ない場合は、コンパイル関数を使用できます。これらの理由から、コンパイル関数のみを使用するディレクティブの例を次に示します。属性を調べますが、ジョブを実行するためにインスタンス スコープは必要ありません。
コンパイル関数のみを使用するディレクティブの例を次に示します。ディレクティブはテンプレート DOM を変換するだけでよいため、コンパイル関数を使用できます。
どちらを使用するかを決定する別の方法: リンク関数で「要素」パラメーターを使用しない場合、おそらくリンク関数は必要ありません。
ほとんどのディレクティブにはリンク機能があるため、例を提供するつもりはありません。非常に簡単に見つけることができるはずです。
コンパイル関数とリンク関数 (またはリンク前関数とリンク後関数) が必要な場合、コンパイル関数はリンク関数を返さなければならないことに注意してください。これは、「コンパイル」属性が定義されている場合、「リンク」属性が無視されるためです。
こちらもご覧ください
コンパイラ
コンパイラは、属性を探してDOMをトラバースするAngularサービスです。コンパイルプロセスは2つのフェーズで行われます。
コンパイル: DOMをトラバースし、すべてのディレクティブを収集します。結果はリンク関数です。
リンク:ディレクティブをスコープと組み合わせて、ライブビューを生成します。スコープモデルでの変更はすべてビューに反映され、ビューに対するユーザーの操作はすべてスコープモデルに反映されます。スコープモデルを信頼できる唯一の情報源にする。
このような一部のディレクティブ
ng-repeat
は、コレクション内のアイテムごとにDOM要素を1回複製します。クローンテンプレートをコンパイルする必要があるのは1回だけで、クローンインスタンスごとに1回リンクするだけでよいため、コンパイルとリンクのフェーズがあるとパフォーマンスが向上します。
したがって、少なくとも場合によっては、最適化として2つのフェーズが別々に存在します。
DOM変換を行う場合は、である必要があります
compile
。動作の変更であるいくつかの機能を追加する場合は、に含める必要がありlink
ます。
これは、ディレクティブに関する Misko の講演からのものです。http://youtu.be/WqmeI5fZcho?t=16m23s
コンパイラ機能は、テンプレートで機能するものと、たとえばクラスをテンプレートに追加するなどしてテンプレート自体を変更できるものと考えてください。ただし、リンク関数はスコープにアクセスでき、特定のテンプレートのインスタンス化ごとに 1 回実行されるリンク関数であるため、実際に 2 つをバインドする作業を行うのはリンク関数です。したがって、コンパイル関数内に配置できる唯一の種類のものは、すべてのインスタンスに共通のものです。
スレッドに少し遅れました。しかし、将来の読者のために:
Angular JS でのコンパイルとリンクを非常に優れた方法で説明している次のビデオに出くわしました。
https://www.youtube.com/watch?v=bjFqSyddCeA
ここにすべての内容をコピー/入力するのは好ましくありません。ビデオからいくつかのスクリーンショットを撮りました。これは、コンパイル フェーズとリンク フェーズのすべての段階を説明しています。
2 番目のスクリーンショットは少し紛らわしいです。しかし、ステップの番号付けに従うと、非常に簡単です。
最初のサイクル: 最初にすべてのディレクティブに対して「コンパイル」が実行されます。
2 サイクル目: 「Controller」と「Pre-Link」が実行されます (1 つずつ) 3 サイクル目: 「Post-Link」が逆の順序で実行されます (最も内側から開始)
以下は、上記を示すコードです。
var app = angular.module('app', []); app.controller('msg', ['$scope', function($scope){ }]); app.directive('メッセージ', function($interpolate){ 戻る{ コンパイル:関数(tElement、tAttributes){ console.log(tAttributes.text + " -コンパイル中.."); 戻る { 前: 関数 (スコープ、iElement、iAttributes、コントローラー){ console.log(iAttributes.text + " -In pre.."); }、 投稿: 関数 (スコープ、iElement、iAttributes、コントローラー){ console.log(iAttributes.text + " -In Post.."); } } }、 コントローラ: 関数($scope, $element, $attrs){ console.log($attrs.text + " - コントローラー内.."); }、 } });
<body ng-app="app">
<div ng-controller="msg">
<div message text="first">
<div message text="..second">
<div message text="....third">
</div>
</div>
</div>
</div>
アップデート:
同じビデオのパート 2 はこちらから入手できます: https://www.youtube.com/watch?v=1M3LZ1cu7rw このビデオでは、Angular JS のコンパイルおよびリンク プロセス中に DOM を変更し、イベントを処理する方法について、簡単な例で詳しく説明しています。 .
2 つのフェーズ: コンパイルとリンク
コンパイル:
ディレクティブ (要素 / 属性 / クラス / コメント) を探して DOM ツリーをトラバースします。ディレクティブをコンパイルするたびに、そのテンプレートが変更されるか、まだコンパイルされていない内容が変更される場合があります。ディレクティブが一致すると、リンク関数が返されます。この関数は、後のフェーズで要素をリンクするために使用されます。コンパイル フェーズの最後には、コンパイルされたディレクティブとそれに対応するリンク関数のリストが表示されます。
リンク:
要素がリンクされると、DOM ツリーは DOM ツリーの分岐点で壊れ、内容はテンプレートのコンパイル済み (およびリンク済み) のインスタンスに置き換えられます。元の置き換えられたコンテンツは破棄されるか、トランスクルージョンの場合はテンプレートに再リンクされます。トランスクルージョンでは、2 つのピースが再びリンクされます (テンプレート ピースが中央にあるチェーンのようなものです)。リンク関数が呼び出されると、テンプレートは既にスコープにバインドされており、要素の子として追加されています。リンク機能は、DOM をさらに操作し、変更リスナーをセットアップする機会です。
この質問は古いので、役立つ短い要約を作成したいと思います。