1

分離ディレクティブとネストされたトランスクルージョンに関する問題に遭遇しました。うまくいけば、何が起こっているのかを教えてくれる人もいます。

簡単に言うと、2 つのディレクティブがあり、それぞれに独自の isolate スコープがあります。

  • テンプレート付き<div b><div ng-transclude></div></div>
  • b このテンプレートを使用し<div><div ng-transclude></div><div>ます。

私が使うとき

  • <div a>{{greeting}}</div> その後、挨拶は表示されません
  • <div a>{{somePrivatePropertyOfA>></div>次に、分離スコープのプロパティを確認できます。

ディレクティブのスコープが分離されていない場合、プライベート プロパティは漏れず、挨拶が表示されます。

私がやろうとしていることをより詳細に説明するplnkr の例を作成しました。また、分離されたスコープのプライベート プロパティがテンプレートに漏れていることも示しています。

この問題は、独自のコンパイル関数を作成することで特定のケースで解決できると思いますが、トランスクルージョンされたコンテンツがディレクティブ a の分離スコープにバインドまたは継承される理由を理解したいと思います。

4

1 に答える 1

1

この質問はかなり古いので、おそらく答えを見つけたでしょうが、他の人が役に立つと思うかもしれないので、私はまだ説明しようとしています.

独立したスコープで作業し、ng-transcludeディレクティブを使用してコンテンツをトランスクルージョンする場合、覚えておくべき 3 つのことがあります。

  1. 分離されたスコープは、親のプロパティを継承しないことを意味します。スコープ オブジェクト内で明示的にバインドしたプロパティのみを継承します。
  2. トランスクルージョンされたコンテンツは、挿入された後にのみコンパイルおよびリンクされます。
  3. ng-transcludeコンテンツをトランスクルージョンするディレクティブの新しい兄弟スコープを作成します。ただし、これはバージョン 1.3.0 から変更される可能性があります。ng -transclude は新しい兄弟スコープを作成しないでください

例で何が起こっているかを理解する最善の方法は、スコープ ツリーを確認することです。

< Scope (002) : ng-app
    < Scope (003) ng-controller
        < Scope (004) : b
        < Scope (005) : ng-transclude <--- Content rendered under this scope
        < Scope (006) : aIsolated
            < Scope (007) : b
            < Scope (008) : ng-transclude
                < Scope (009) : ng-transclude <--- Content rendered under this scope
        < Scope (00A) : aNotIsolated
            < Scope (00B) : b
            < Scope (00C) : ng-transclude
                < Scope (00D) : ng-transclude <--- Content rendered under this scope

最初の例では、Angular はbディレクティブを見つけます。コンテンツを取り出し、分離されたスコープを作成し、そのテンプレートをコンパイルします。テンプレートをコンパイルすると、ng-transcludeディレクティブが見つかります。新しい兄弟スコープを作成し、コンテンツを挿入します。ng-transcludeのスコープは兄弟であるため、その親はですng-controller。したがって、コンテンツはMainCtrlコントローラーのすべてのプロパティを継承します。

2 番目の例では、Angular がaIsolatedディレクティブを見つけます。コンテンツを取り出し、分離されたスコープを作成し、そのテンプレートをコンパイルします。テンプレートをコンパイルすると、bディレクティブが検出され、コンパイルが開始されbます。ディレクティブによってラップされたコンテンツを取り出し、b分離された子スコープを作成bし、テンプレートをコンパイルします。bテンプレートをコンパイルすると、ng-transcludeディレクティブが見つかります。新しい兄弟スコープを作成し、コンテンツを挿入します。つまり、この新しい兄弟スコープはtransclude、コンテンツをng-transcludeスコープの子にする関数に渡されます。次に、別のディレクティブが見つかった場所でコンテンツのコンパイルを開始するng-transcludeため、新しいスコープを作成し、コンテンツを挿入し{{message}}ます{{private}}式を入れます。最後に、式をコンパイルしてリンクします。しかし、継承ツリーを見ると、コンテンツがaIsolatedスコープのプロパティを継承していることがわかります。これにより、分離されたスコープになります。

aIsolatedディレクティブには分離されたスコープがあるため、親スコープで定義されたプロパティにアクセスできないため、コンテンツはコントローラーprivateで定義したプロパティを読み取ります。aIsolated次に、ディレクティブbは分離されたスコープも作成し、それにprivateプロパティを追加しますが、分離されているため、親のプロパティをオーバーライドしていません。したがって、すべてのディレクティブのコンパイルとリンクが完了すると、ディレクティブで定義されているプロパティがand式aIsolatedに入れられます。プロパティが存在しないため、空です。{{message}}{{private}}message

3 番目の例のコンパイル プロセスは、2 番目の例とまったく同じです。aNotIsolated独自のスコープを作成するだけで、MainCtrlコントローラーで定義されたプロパティを継承するディレクティブのみが異なります。

ディレクティブのスコープが分離されていない場合、プライベート プロパティは漏れず、挨拶が表示されます。

それは完全に真実ではありません。このように表示される理由はaNotIsolated、 が独自のprivateプロパティを定義していないためです。ここで私の例 aNotIsolatedでは、コントローラーでプロパティを定義privateしているため、プライベートメッセージが例とは異なることがわかります。

また、何が起こっているのかを説明するのに、漏れは適切な言葉ではありません。式は、挿入先のスコープで評価されます。そのため{{message}}、 and{{private}}式はスコープの下で評価され、スコープは,またはスコープng-transcludeのいずれかから継承されます。MainCtrlaIsolatedaNotIsolated

于 2013-12-19T16:03:03.657 に答える