2013-09-26 13 views
5

私が抱えている問題はhttp://jsfiddle.net/miketheanimal/2CcYp/13/で確認できます。これは問題を最小限に抑えます。ネストされたディレクティブと親スコープ

私はコントローラー "main"と、transcludeの "outer"と、そうでないディレクティブ "inner"を持っています。各ディレクティブには、分離スコープとコントローラがあります。メインとディレクティブのコントローラは$ scope._name = '...'を設定しているので、それらを分けることができます。

var module = angular.module('miketa', []); 
function main ($scope) { 
    $scope._name = 'main' ; 
} ; 
module.directive('outer', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     scope: {}, 
     template: '<div><div ng-transclude></div></div>', 
     controller: [ '$scope', function($scope) { 
      $scope._name = 'outer' ; 
      document.getElementById('opn').innerHTML = $scope.$parent._name ; 
     }]}}); 
module.directive('inner', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: {}, 
     template: '<div></div>', 
     controller: [ '$scope', function($scope) { 
      $scope._name = 'inner' ; 
      document.getElementById('ipn').innerHTML = $scope.$parent._name ; 
     }]}}); 

HTMLはこれらをメイン→外側→内側にネストします。ディレクティブのコントローラ関数は、親のスコープ名(つまり、* $ scope。$ parent._name)をレンダリングされたHTMLにコピーします(DOMを直接操作するための謝辞、それは名前を表示する最も簡単な方法でした)。

私はないです、と私は(すなわちから名前を表示するようにインナーを期待コントローラ(すなわち、「メイン」)から名前を表示するようにを期待します。」アウター ")、これはそうではなく、むしろ"メイン "も示​​す。

問題は、実際に本物のコードであるため現れ、Iは内側外側スコープとの間に結合したいが、内側メイン範囲に結合してしまいます。

+0

私はあなたの外側の範囲が分離されていると思うので、あなたはそれをどのようにすることができますか? –

+0

はい、スコープは分離されているのでプロトタイプ的に継承されませんが、親スコープ($ scope。$ parent bit)を持ち、これらは期待通りの動作をしていないようです(inner - > outer- >メイン)。私は最後の段落で述べたように、* inner *と* outer *のスコープ(つまりinner * scope:{innervar: '= outervar'} *)の間でバインドしようとすると、これが問題になります。 –

+0

ああ、ng-transcludeは、範囲をfalseに設定しました! –

答えて

9

実際、これはバグではなく、望ましい動作です。 docs on the $compile serviceから:

典型的なセットアップでウィジェットが分離株のスコープを作成しますが、 トランスクルーは子供ではなく、分離株スコープの兄弟。この は、ウィジェットがプライベート状態を持ち、 転置を親(事前分離)スコープにバインドすることを可能にします。

も参照してください:Why ng-transclude's scope is not a child of its directive's scope - if the directive has an isolated scope?

あなたは本当にそれがng-transcludeを忘れて行う仕事を取得する必要がある場合:

var module = angular.module('miketa', []); 

function main($scope) { 
    $scope._name = 'main'; 
}; 
module.directive('outer', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: {}, 
     template: '<div><inner></inner></div>', 
     controller: ['$scope', function ($scope) { 
      $scope._name = 'outer'; 
      document.getElementById('opn').innerHTML = $scope.$parent._name; 
     }] 
    } 
}); 
module.directive('inner', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: {}, 
     template: '<div></div>', 
     controller: ['$scope', function ($scope) { 
      $scope._name = 'inner'; 
      document.getElementById('ipn').innerHTML = $scope.$parent._name; 
     }] 
    } 
}); 

出来上がり!できます。

+0

私はtranscludeに何か関係があるかどうか疑問に思っていました。しかし、あなたの変化はむしろ*アウター*を無意味にしてしまいます。私がしようとしているのは、別のコンテンツ(つまり、inner1 *と* inner2 *をラップする)をラップできるディレクティブ* outer *を持つことです。私はそれを行うことができる方法はありますか? –

+0

どんなng-trnascludeもスコープを隔離する必要はありません。あなたがリンクのスレッドとドキュメントを読んだら、AngularJSnの転覆の論理です。 –

+0

よろしくお願いします。ドローイングボードに戻る:) –

関連する問題