なんて素晴らしい質問でしょう!他の方の意見も聞きたいのですが、私が使用しているガイドラインを以下に示します。
高高度の前提: スコープは、親コントローラー、ディレクティブ、およびディレクティブ テンプレート間の通信に使用する「接着剤」として使用されます。
親スコープ: scope: false
、したがって新しいスコープはまったくありません
私はこれをあまり頻繁に使用しませんが、@MarkRajcok が言ったように、ディレクティブがスコープ変数にアクセスしない場合 (そして明らかに何も設定しない場合)、私に関する限り、これは問題ありません。これは、親ディレクティブのコンテキストでのみ使用され (これには常に例外があります)、テンプレートを持たない子ディレクティブにも役立ちます。基本的に、テンプレートを使用するものはすべてスコープを共有するものではありません。これは、アクセスと操作のためにそのスコープを本質的に公開しているためです (ただし、この規則には例外があると確信しています)。
例として、私は最近、作成中の SVG ライブラリを使用して (静的) ベクター グラフィックを描画するディレクティブを作成しました。2つ$observe
の属性 (width
とheight
) があり、それらを計算に使用しますが、スコープ変数の設定も読み取りも行わず、テンプレートもありません。これは、別のスコープを作成しない場合の適切な使用例です。私たちはそれを必要としないので、なぜ気にするのですか?
しかし、別の SVG ディレクティブでは、使用するデータのセットが必要であり、さらに少量の状態を保存する必要がありました。この場合、親スコープを使用することは無責任です (繰り返しますが、一般的に言えば)。代わりに...
子スコープ: scope: true
子スコープを持つディレクティブはコンテキストを認識し、現在のスコープと対話することを目的としています。
明らかに、isolate スコープに対するこれの主な利点は、ユーザーが必要な属性に対して自由に補間を使用できることです。たとえばclass="item-type-{{item.type}}"
、isolate スコープを持つディレクティブを使用すると、デフォルトでは機能しませんが、子スコープを持つディレクティブでは正常に機能します。また、ディレクティブ自体は、親の汚染や損傷を心配することなく、独自のスコープのコンテキストで属性と式を安全に評価できます。
たとえば、ツールチップは追加されるだけのものです。ここで他のディレクティブまたは補間された属性を使用することが予想されるため、isolate スコープは機能しません (デフォルトでは、以下を参照)。ツールチップは単なる拡張機能です。しかし、ツールチップは、サブディレクティブおよび/またはテンプレートで使用するためにスコープにいくつかのものを設定する必要があり、明らかにそれ自体の状態を管理する必要があるため、親スコープを使用するのは実際にはかなり悪いでしょう. 私たちはそれを汚染するか、損傷するかのどちらかであり、どちらもブエノではありません.
私は子スコープを分離スコープや親スコープよりも頻繁に使用していることに気づきました。
スコープを分離: scope: {}
これは再利用可能なコンポーネント用です。:-)
しかし、真剣に、「再利用可能なコンポーネント」を「自己完結型のコンポーネント」と考えています。その意図は、それらを特定の目的に使用することであるため、それらを他のディレクティブと組み合わせたり、他の補間属性を DOM ノードに追加したりすることは、本質的に意味がありません。
より具体的には、このスタンドアロン機能に必要なものはすべて、親スコープのコンテキストで評価される指定された属性を通じて提供されます。それらは、一方向の文字列 ('@')、一方向の式 ('&')、または双方向の変数バインディング ('=') のいずれかです。
自己完結型のコンポーネントでは、それ自体が存在するため、他のディレクティブや属性を適用する必要はありません。そのスタイルは独自のテンプレートによって管理され (必要な場合)、適切なコンテンツをトランスクルードすることができます (必要な場合)。これはスタンドアロンなので、isolate スコープに入れて、「これをいじらないでください。これらのいくつかの属性を介して定義済みの API を提供します」とも言います。
良いベスト プラクティスは、ディレクティブ リンクとコントローラー関数からできるだけ多くのテンプレート ベースのものを除外することです。これにより、もう 1 つの「API のような」構成ポイントが提供されます。ディレクティブのユーザーは、テンプレートを簡単に置き換えることができます。機能はすべて同じままで、その内部 API には一切手を加えていませんが、必要に応じてスタイリングと DOM 実装をいじることができます。ui/bootstrap は、Peter と Pawel が素晴らしいので、これをうまく行う方法の良い例です。
分離スコープは、トランスクルージョンでの使用にも最適です。タブを取ります。それらは機能全体であるだけでなく、その内部にあるものはすべて親スコープ内から自由に評価でき、タブ (およびペイン) は好きなように実行できます。タブには(テンプレートとやり取りする) スコープに属する独自の状態がありますが、その状態はそれが使用されたコンテキストとは関係ありません。さらに、タブで他のディレクティブを使用してもあまり意味がありません。それらはタブです - そして私たちはすでにその機能を持っています!
より多くの機能でそれを囲むか、より多くの機能をトランスクルードしますが、ディレクティブは既にあるものです。
そうは言っても、@ProLoserが彼の答えで示唆したように、isolateスコープの制限(つまり機能)のいくつかを回避する方法があることに注意する必要があります。たとえば、子スコープのセクションで、isolate スコープ (デフォルト) を使用した場合の非ディレクティブ属性の補間について説明しました。ただし、ユーザーは、たとえば、単に使用するだけで、class="item-type-{{$parent.item.type}}"
再び機能する可能性があります。したがって、子スコープよりも分離スコープを使用するやむを得ない理由があるが、これらの制限のいくつかについて心配している場合は、必要に応じてほぼすべての制限を回避できることを知っておいてください。
概要
新しいスコープのないディレクティブは読み取り専用です。それらは完全に信頼されており (つまり、アプリの内部)、ジャックには触れません。子スコープを持つディレクティブは機能を追加しますが、それだけが機能ではありません。最後に、isolate スコープは、全体の目標であるディレクティブ用です。それらはスタンドアロンであるため、それらを悪者に任せても問題ありません (そして最も「正しい」)。
私は最初の考えを出したかったのですが、より多くのことを考えているので、これを更新します. しかし、聖なるがらくた-これはSOの答えには長いです...
PS: 完全に接線ですが、スコープについて話しているので、私は「プロトタイプ」と言う方が好きですが、他の人は「プロトタイプ」を好みます。:-)