指示ロジックにコントローラー関数を使用しているように見える場所もあれば、リンクを使用しているように見える場所もあります。angularホームページのタブの例では、コントローラーを1つに使用し、リンクを別のディレクティブに使用しています。2つの違いは何ですか?
4 に答える
質問を少し拡張し、コンパイル機能も含めます。
compile 関数-テンプレートDOM 操作 (つまり、tElement = テンプレート要素の操作) に使用します。したがって、ディレクティブに関連付けられたテンプレートのすべての DOM クローンに適用される操作です。(リンク関数 (またはプリ リンク関数とポスト リンク関数) も必要で、コンパイル関数を定義した場合、コンパイル関数はリンク関数を返す必要があります。これは、属性が定義さ
'link'
れていると属性が無視されるためです。)'compile'
リンク関数- 通常、リスナー コールバックの登録 (つまり、
$watch
スコープでの式) と、DOM の更新 (つまり、iElement = 個々のインスタンス要素の操作) に使用します。テンプレートが複製された後に実行されます。たとえば、 内では、その特定の要素のテンプレート (tElement) が (iElement に) 複製<li ng-repeat...>
された後に、リンク関数が実行されます。を使用すると、スコープ プロパティの変更をディレクティブに通知できます (スコープは各インスタンスに関連付けられます)。これにより、ディレクティブは、更新されたインスタンス値を DOM にレンダリングできます。<li>
<li>
$watch
コントローラー関数- 別のディレクティブがこのディレクティブと対話する必要がある場合に使用する必要があります。たとえば、AngularJS のホームページでは、ペイン ディレクティブは tabs ディレクティブによって維持されるスコープにそれ自体を追加する必要があるため、tabs ディレクティブは、ペイン ディレクティブがアクセス/呼び出しできるコントローラー メソッド (API と考えてください) を定義する必要があります。
タブとペイン ディレクティブの詳細な説明、および tabs ディレクティブがthis
( on ではなく) を使用してコントローラーに関数を作成する理由については、AngularJS コントローラーの 'this' vs $scope$scope
を参照してください。
一般に、メソッド$watches
などをディレクティブのコントローラーまたはリンク関数のいずれかに配置できます。コントローラーが最初に実行されますが、これは重要な場合があります ( ctrl および link 関数が 2 つのネストされたディレクティブで実行されたときにログに記録されるこのフィドルを参照してください)。Josh がコメントで述べたように、フレームワークの残りの部分との一貫性のために、コントローラー内にスコープ操作関数を配置することをお勧めします。
マークの回答を補完するものとして、コンパイル機能はスコープにアクセスできませんが、リンク機能はアクセスできます。
このビデオを本当にお勧めします。Misko Hevery (AngularJS の父) によるライティング ディレクティブでは、相違点といくつかのテクニックについて説明しています。(動画の14:41あたりのコンパイル機能とリンク機能の違い)。
- コンパイル前のコードの実行:コントローラーを使用
- コンパイル後のコードの実行:リンクを使用
Angular の慣例 : コントローラーにビジネス ロジックを記述し、リンクに DOM 操作を記述します。
これとは別に、別のディレクティブのリンク関数から 1 つのコントローラー関数を呼び出すことができます。たとえば、3 つのカスタム ディレクティブがあります。
<animal>
<panther>
<leopard></leopard>
</panther>
</animal>
「ヒョウ」ディレクティブ内から動物にアクセスしたい。
http://egghead.io/lessons/angularjs-directive-communicationは、ディレクティブ間の通信について知るのに役立ちます
コンパイル機能-
- コントローラーとリンク関数の前に呼び出されます。
- コンパイル機能では、元のテンプレート DOM があるため、AngularJS がそのインスタンスを作成する前、およびスコープが作成される前に、元の DOM に変更を加えることができます。
- ng-repeat は完璧な例です。元の構文はテンプレート要素であり、HTML で繰り返される要素はインスタンスです。
- 複数の要素インスタンスと 1 つのテンプレート要素のみが存在できます
- スコープはまだ利用できません
- コンパイル関数は関数とオブジェクトを返すことができます
- (ポストリンク) 関数を返す - コンパイル関数が空の場合、config オブジェクトの link プロパティを介してリンク関数を登録するのと同じです。
- pre および post プロパティを介して登録された関数を持つオブジェクトを返す - リンク フェーズ中にリンク関数をいつ呼び出す必要があるかを制御できます。以下のプレリンク機能とポストリンク機能に関する情報を参照してください。
構文
function compile(tElement, tAttrs, transclude) { ... }
コントローラ
- コンパイル関数の後に呼び出されます
- スコープはこちら
- 他のディレクティブからアクセスできます (require 属性を参照)
事前リンク
リンク関数は、DOM リスナーの登録と DOM の更新を担当します。テンプレートが複製された後に実行されます。これは、ディレクティブ ロジックのほとんどが置かれる場所です。
angular.element を使用してコントローラーの dom を更新できますが、リンク関数で要素が提供されるため、これはお勧めできません。
事前リンク関数は、angular js が子要素を既にコンパイルしているが、子要素の投稿リンクが呼び出される前に実行されるロジックを実装するために使用されます。
ポストリンク
リンク関数のみを持つディレクティブ、角度は関数を投稿リンクとして扱います
post はコンパイル、コントローラー、プリリンク関数の後に実行されるため、これがディレクティブ ロジックを追加する最も安全でデフォルトの場所と見なされます。