Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit bf79bd4

Browse files
committed
fix(ngTransclude): make the transclusion available to parent post-link
previously the translusion was appended the the ngTranslude element via $evalAsync which makes the transluded dom unavailable to parent post-linking functions. By appending translusion in linking phase, post-linking functions will be able to access it.
1 parent 5c4ffb3 commit bf79bd4

File tree

2 files changed

+69
-10
lines changed

2 files changed

+69
-10
lines changed

src/ng/directive/ngTransclude.js

+11-9
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,16 @@
4949
*
5050
*/
5151
var ngTranscludeDirective = ngDirective({
52-
controller: ['$transclude', '$element', '$scope', function($transclude, $element, $scope) {
53-
// use evalAsync so that we don't process transclusion before directives on the parent element even when the
54-
// transclusion replaces the current element. (we can't use priority here because that applies only to compile fns
55-
// and not controllers
56-
$scope.$evalAsync(function() {
57-
$transclude(function(clone) {
58-
$element.append(clone);
59-
});
52+
controller: ['$transclude', function($transclude) {
53+
// remember the transclusion fn but call it during linking so that we don't process transclusion before directives on
54+
// the parent element even when the transclusion replaces the current element. (we can't use priority here because
55+
// that applies only to compile fns and not controllers
56+
this.$transclude = $transclude;
57+
}],
58+
59+
link: function($scope, $element, $attrs, controller) {
60+
controller.$transclude(function(clone) {
61+
$element.append(clone);
6062
});
61-
}]
63+
}
6264
});

test/ng/compileSpec.js

+58-1
Original file line numberDiff line numberDiff line change
@@ -2823,10 +2823,67 @@ describe('$compile', function() {
28232823
expect(jqLite(element.find('span')[1]).text()).toEqual('T:true');
28242824
});
28252825
});
2826+
2827+
2828+
it('should make the result of a transclusion available to the parent directive in post-linking phase (template)',
2829+
function() {
2830+
module(function() {
2831+
directive('trans', function(log) {
2832+
return {
2833+
transclude: true,
2834+
template: '<div ng-transclude></div>',
2835+
link: {
2836+
pre: function($scope, $element) {
2837+
log('pre(' + $element.text() + ')');
2838+
},
2839+
post: function($scope, $element) {
2840+
log('post(' + $element.text() + ')');
2841+
}
2842+
}
2843+
};
2844+
});
2845+
});
2846+
inject(function(log, $rootScope, $compile) {
2847+
element = $compile('<div trans><span>unicorn!</span></div>')($rootScope);
2848+
$rootScope.$apply();
2849+
expect(log).toEqual('pre(); post(unicorn!)');
2850+
});
2851+
});
2852+
2853+
2854+
it('should make the result of a transclusion available to the parent directive in pre- and post- linking phase (templateUrl)',
2855+
function() {
2856+
// when compiling an async directive the transclusion is always processed before the directive
2857+
// this is different compared to sync directive. delaying the transclusion makes little sense.
2858+
2859+
module(function() {
2860+
directive('trans', function(log) {
2861+
return {
2862+
transclude: true,
2863+
templateUrl: 'trans.html',
2864+
link: {
2865+
pre: function($scope, $element) {
2866+
log('pre(' + $element.text() + ')');
2867+
},
2868+
post: function($scope, $element) {
2869+
log('post(' + $element.text() + ')');
2870+
}
2871+
}
2872+
};
2873+
});
2874+
});
2875+
inject(function(log, $rootScope, $compile, $templateCache) {
2876+
$templateCache.put('trans.html', '<div ng-transclude></div>');
2877+
2878+
element = $compile('<div trans><span>unicorn!</span></div>')($rootScope);
2879+
$rootScope.$apply();
2880+
expect(log).toEqual('pre(unicorn!); post(unicorn!)');
2881+
});
2882+
});
28262883
});
28272884

28282885

2829-
describe('img[src] sanitization', function($sce) {
2886+
describe('img[src] sanitization', function() {
28302887
it('should NOT require trusted values for img src', inject(function($rootScope, $compile, $sce) {
28312888
element = $compile('<img src="{{testUrl}}"></img>')($rootScope);
28322889
$rootScope.testUrl = 'http://example.com/image.png';

0 commit comments

Comments
 (0)