I have a very simple setup:
Title in parent (transcluded): {{title}}
and
angular.mo
The scope of the transcluded element is not a child scope of the directive but a sibling one. This is what documentation says:
In a typical setup the widget creates an isolate scope, but the transclusion is not a child, but a sibling of the isolate scope.
The simplest solution in this case how you can access transcuded scope is like this:
.directive('pane', function () {
return {
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
template:
'<div>' +
'<div>Title in isolated scope: {{title}}</div>' +
'<div ng-transclude></div>' +
'</div>',
link: function (scope, element, attrs) {
scope.$$nextSibling.title = attrs.title;
}
};
});
@dfsq is correct about:
The scope of the transcluded element is not a child scope of the directive but a sibling one
I'd like to add more comments why this is the expected behavior of angularJs. As the docs says:
In a typical setup the widget creates an isolate scope, but the transclusion is not a child, but a sibling of the isolate scope. This makes it possible for the widget to have private state, and the transclusion to be bound to the parent (pre-isolate) scope.
The transcluded content inside the directive is arbitrary, it should not have knowledge about the directive's isolate scope, otherwise, we would create a tight coupling code. Because for the transcluded content to work, the content must know the implementation details of your directive (what is available to use).
If you decide that the content belongs to the directive. You have 2 options:
1) Make the content part of the template
angular.module('transclude', [])
.directive('pane', function(){
return {
restrict: 'E',
transclude: true,
scope: { title:'@' },
template: '<div>' +
'<div>Title in isolated scope: {{title}}</div>' +
'<div>' +
' Title in parent (transcluded): {{title}} ' +
' </div>' +
'</div>'
};
});
DEMO
2) Use custom tranclusion to bind the scope yourself:
angular.module('transclude', [])
.directive('pane', function(){
return {
restrict: 'E',
transclude: true,
scope: { title:'@' },
template: '<div>' +
'<div>Title in isolated scope: {{title}}</div>' +
'<div class="transclude"></div>' +
'</div>',
link: function (scope, element, attr,controller, linker) {
linker(scope, function(clone){
element.find(".transclude").append(clone); // add to DOM
});
}
};
});
DEMO