web-dev-qa-db-ja.com

ディレクティブのコンパイル関数の `preLink`はいつ使用しますか?

Angularjs 'ディレクティブのcompile関数には、preLinkpostLinkの2つの関数があります。

プレリンク機能

子要素がリンクされる前に実行されます。コンパイラーのリンク関数はリンクするための正しい要素を見つけられないため、DOM変換を行うのは安全ではありません。

ポストリンク機能

子要素がリンクされた後に実行されます。ポストリンク機能でDOM変換を行っても安全です。

preLinkで何をすべきでないかを示していますが、preLinkをいつ、何を使用すべきか疑問に思います。ほとんどの場合、私はpostLinkを使用しました。使わなければならない場合はありますか?

37
Freewind

preLinkを使用する必要はほとんどありません。有効なケースは、スコープ内のデータを操作する必要がある場合ですがDOMではありませんbeforelink関数(他のディレクティブも)が実行されます。

Jacobがコメントしたように、コントローラーからでもいつでもそれを行うことができますが、ディレクティブ自体にコードを含める方が適切な場合もあります。

リンクの順序が適切に説明されている場合のディレクティブの動作に関する優れた記事があります。 http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs -ディレクティブ/

事前リンクが必要になることがある理由の良い例が必要な場合は、angularディレクティブ自体のコードを確認することをお勧めします。たとえば https://github.com/ angular/angular.js/blob/master/src/ng/directive/ngModel.js

13
iwein

preLink関数は、ディレクティブが何かをsharedスコープに入れて、他のディレクティブがpostLink関数で使用できるようにする場合に使用されます。

Angularのformディレクティブは、たとえば、すべての入力のエントリを含むオブジェクトを作成します。カスタムディレクティブは、postLink関数でこのオブジェクトに安全にアクセスできます。

7
a better oliver

他のディレクティブを含むカスタムディレクティブを作成するときは、preLinkを使用する必要がありました。私の場合、ディレクティブには、Angular UI BootstrapのTypeaheadディレクティブをその要素の一部に適用し、独自のスコープ変数を使用してTypeahead機能を初期化するテンプレートが含まれていました。

例えば:

...
template:
    "<select ng-show='dropdown' class='form-control' ng-model='ngModel' ng-options='s for s in suggestions'></select>"
    + "<textarea ng-show='!dropdown' class='form-control' ng-model='ngModel' typeahead='s for s in suggestions |filter:$viewValue' typeahead-min-length='0' typeahead-editable='{{editable}}'></textarea>",
...

その場合、Angularは親の前に子ディレクティブをリンクするため、preLinkを使用して先行入力を設定する必要がありました。ディレクティブで$ scope.dropdown変数と$ scope.editable変数を初期化すると、 postLink関数、先行入力ディレクティブがリンクされたときに初期化されなかったことがわかりました。このディレクティブを正しく機能させるには、初期化をpreLinkに移動する必要がありました。

6
Derek