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

Commit faf5b98

Browse files
committed
fix($compile): instantiate controlers when re-entering compilation
When we re-enter compilation either due to async directive templates or element transclude directive we need to keep track of controllers to instantiate during linking. This piece of info was missing when re-entering compilation and that's what this commit fixes. I also reordered the properties in the previousCompileContext object. Closes #4434 Closes #4616
1 parent e57d5b8 commit faf5b98

File tree

2 files changed

+64
-8
lines changed

2 files changed

+64
-8
lines changed

src/ng/compile.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -1117,16 +1117,16 @@ function $CompileProvider($provide) {
11171117

11181118
var terminalPriority = -Number.MAX_VALUE,
11191119
newScopeDirective,
1120+
controllerDirectives = previousCompileContext.controllerDirectives,
11201121
newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
11211122
templateDirective = previousCompileContext.templateDirective,
1123+
transcludeDirective = previousCompileContext.transcludeDirective,
11221124
$compileNode = templateAttrs.$$element = jqLite(compileNode),
11231125
directive,
11241126
directiveName,
11251127
$template,
1126-
transcludeDirective = previousCompileContext.transcludeDirective,
11271128
replaceDirective = originalReplaceDirective,
11281129
childTranscludeFn = transcludeFn,
1129-
controllerDirectives,
11301130
linkFn,
11311131
directiveValue;
11321132

@@ -1191,9 +1191,10 @@ function $CompileProvider($provide) {
11911191

11921192
childTranscludeFn = compile($template, transcludeFn, terminalPriority,
11931193
replaceDirective && replaceDirective.name, {
1194+
controllerDirectives: controllerDirectives,
11941195
newIsolateScopeDirective: newIsolateScopeDirective,
1195-
transcludeDirective: transcludeDirective,
1196-
templateDirective: templateDirective
1196+
templateDirective: templateDirective,
1197+
transcludeDirective: transcludeDirective
11971198
});
11981199
} else {
11991200
$template = jqLite(jqLiteClone(compileNode)).contents();
@@ -1259,9 +1260,10 @@ function $CompileProvider($provide) {
12591260

12601261
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
12611262
templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, {
1263+
controllerDirectives: controllerDirectives,
12621264
newIsolateScopeDirective: newIsolateScopeDirective,
1263-
transcludeDirective: transcludeDirective,
1264-
templateDirective: templateDirective
1265+
templateDirective: templateDirective,
1266+
transcludeDirective: transcludeDirective
12651267
});
12661268
ii = directives.length;
12671269
} else if (directive.compile) {
@@ -1415,7 +1417,7 @@ function $CompileProvider($provide) {
14151417
return parentGet(parentScope, locals);
14161418
};
14171419
break;
1418-
1420+
14191421
default:
14201422
throw $compileMinErr('iscp',
14211423
"Invalid isolate scope definition for directive '{0}'." +
@@ -1819,7 +1821,7 @@ function directiveNormalize(name) {
18191821
/**
18201822
* @ngdoc object
18211823
* @name ng.$compile.directive.Attributes
1822-
*
1824+
*
18231825
* @description
18241826
* A shared object between directive compile / linking functions which contains normalized DOM
18251827
* element attributes. The the values reflect current binding state `{{ }}`. The normalization is

test/ng/compileSpec.js

+54
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,60 @@ describe('$compile', function() {
22822282
});
22832283

22842284

2285+
it('should get required controller via linkingFn (template)', function() {
2286+
module(function() {
2287+
directive('dirA', function() {
2288+
return {
2289+
controller: function() {
2290+
this.name = 'dirA';
2291+
}
2292+
};
2293+
});
2294+
directive('dirB', function(log) {
2295+
return {
2296+
require: 'dirA',
2297+
template: '<p>dirB</p>',
2298+
link: function(scope, element, attrs, dirAController) {
2299+
log('dirAController.name: ' + dirAController.name);
2300+
}
2301+
};
2302+
});
2303+
});
2304+
inject(function(log, $compile, $rootScope) {
2305+
element = $compile('<div dir-a dir-b></div>')($rootScope);
2306+
expect(log).toEqual('dirAController.name: dirA');
2307+
});
2308+
});
2309+
2310+
2311+
it('should get required controller via linkingFn (templateUrl)', function() {
2312+
module(function() {
2313+
directive('dirA', function() {
2314+
return {
2315+
controller: function() {
2316+
this.name = 'dirA';
2317+
}
2318+
};
2319+
});
2320+
directive('dirB', function(log) {
2321+
return {
2322+
require: 'dirA',
2323+
templateUrl: 'dirB.html',
2324+
link: function(scope, element, attrs, dirAController) {
2325+
log('dirAController.name: ' + dirAController.name);
2326+
}
2327+
};
2328+
});
2329+
});
2330+
inject(function(log, $compile, $rootScope, $templateCache) {
2331+
$templateCache.put('dirB.html', '<p>dirB</p>');
2332+
element = $compile('<div dir-a dir-b></div>')($rootScope);
2333+
$rootScope.$digest();
2334+
expect(log).toEqual('dirAController.name: dirA');
2335+
});
2336+
});
2337+
2338+
22852339
it('should support controllerAs', function() {
22862340
module(function() {
22872341
directive('main', function() {

0 commit comments

Comments
 (0)