The problem I have can be see at http://jsfiddle.net/miketheanimal/2CcYp/13/ This strips down my problem to a minimum.
I have a controller "main", a directive "outer" which transclude's, and a directive "inner" which doesn't. Each directive has an isolate scope and a controller. The main and the directive controllers set $scope._name = '...' so I can tell them apart.
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 ;
}]}});
The HTML nests these as main -> outer -> inner. The controller functions in the directives copy their parent scope name (ie., *$scope.$parent._name) into the rendered HTML (apologies for manipulating the DOM directly, it was the easiest way to display the names!).
I would expect outer to show the name from the controller (ie., "main") which is does, and I'd expect inner to show the name from outer (ie., "outer"), which is doesn't, rather it shows "main" as well.
The problem actually manifests itself since in the real code, I'd like to bind between the inner and outer scopes, but inner ends up binding to the main scope.