5

私が抱えている問題はhttp://jsfiddle.net/miketheanimal/2CcYp/13/で確認できます。これにより、問題が最小限に抑えられます。

コントローラー「メイン」、トランスクルードのディレクティブ「アウター」、トランスクルードしないディレクティブ「インナー」があります。各ディレクティブには、分離スコープとコントローラーがあります。メイン コントローラーとディレクティブ コントローラーは $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 を直接操作して申し訳ありません。名前を表示する最も簡単な方法でした!)。

私は、 outerがコントローラーから名前を表示することを期待します (つまり、「main」)。むしろ、「メイン」も表示されます。

実際のコードでは、内側外側のスコープ間でバインドしたいのですが、内側メインスコープにバインドされるため、問題は実際に現れます。

4

1 に答える 1

9

実際、これはバグではなく、望ましい動作です。サービスドキュメント$compileから:

一般的な設定では、ウィジェットは分離スコープを作成しますが、トランスクルージョンは分離スコープの子ではなく、兄弟です。これにより、ウィジェットにプライベートな状態を持たせ、トランスクルージョンを親 (分離前) スコープにバインドすることが可能になります。

参照: ng-transclude のスコープがそのディレクティブのスコープの子ではないのはなぜですか - ディレクティブに孤立したスコープがある場合は?

本当にそれを機能させる必要がある場合は、忘れ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;
        }]
    }
});

そして出来上がり!できます。

于 2013-09-26T11:44:41.187 に答える