2013-09-26 107 views
5

我有的問題可以在http://jsfiddle.net/miketheanimal/2CcYp/13/看到,這可以將我的問題降到最低。嵌套指令和父範圍

我有一個控制器「主」,一個指令「外」,transclude的和一個指令「內部」,而不是。每個指令都有一個隔離範圍和一個控制器。主控制器和指令控制器設置$ 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把這些嵌套爲main - > outer - > inner。控制器在指令中的作用是將作用域名(例如* $ scope。$ parent._name)的複製到呈現的HTML中(直接操作DOM的道歉操作,這是顯示名稱的最簡單方法!)。

我期望來自控制器顯示名稱(即,「主」),這是確實的,我會期望從顯示名稱(即,「外部「),這不是,而是顯示」主要「。

這個問題實際上表現由於在實際的代碼,我想在作用域之間結合的,但最終結合範圍。

+0

這是相當邏輯,我認爲你的外部範圍是隔離的,所以你可以如何遺傳它? –

+0

是的,範圍是孤立的,所以它們不會原型繼承,但它們確實有父範圍($ scope。$ parent bit),並且這些似乎並不按我期望的方式工作(內部 - >外部 - >主)。正如我在最後一段中指出的,當我試圖在* inner *和* outer *的範圍(即內部*範圍內:{innervar:'= outervar'} *)之間進行綁定時,這會成爲問題。 –

+0

啊ng-transclude將ng-scope設置爲false! –

回答

9

事實上,它不是一個錯誤,它是所需的行爲。從docs on the $compile service

在典型的設置窗口小部件創建一個分離的範圍,但 transclusion是不是一個孩子,而是分離範圍的兄弟姐妹。這個 可以使小部件具有私有狀態,並且 跨接被綁定到父(預隔離)範圍。

參見: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是否與它有關,我發現了一些其他類似但不太相關的帖子。但是你的改變讓* outer *變得毫無意義,我不妨把它推到* inner *中。我想要做的是有一個指令* outer *,可以包裝不同的內容(即,wrap * inner1 *和* inner2 *等)。有什麼辦法可以做到嗎? –

+0

沒有任何ng-trnasclude隔離你必須接受的範圍!這是AngularJSn中包含的邏輯,如果你閱讀鏈接線程和文檔 –

+0

好的,謝謝。回到繪圖板:) –