aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Minar2013-10-21 17:38:43 -0700
committerIgor Minar2013-10-24 13:54:15 -0700
commitfaf5b980da09da2b4c28f1feab33f87269f9f0ba (patch)
treeca03fa2156eaa8389367690972bda2b4e6ade396
parente57d5b89caac88a11696e88ccdd5404f77663447 (diff)
downloadangular.js-faf5b980da09da2b4c28f1feab33f87269f9f0ba.tar.bz2
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
-rw-r--r--src/ng/compile.js18
-rwxr-xr-xtest/ng/compileSpec.js54
2 files changed, 64 insertions, 8 deletions
diff --git a/src/ng/compile.js b/src/ng/compile.js
index 2ff9144b..e6300f15 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -1117,16 +1117,16 @@ function $CompileProvider($provide) {
var terminalPriority = -Number.MAX_VALUE,
newScopeDirective,
+ controllerDirectives = previousCompileContext.controllerDirectives,
newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
templateDirective = previousCompileContext.templateDirective,
+ transcludeDirective = previousCompileContext.transcludeDirective,
$compileNode = templateAttrs.$$element = jqLite(compileNode),
directive,
directiveName,
$template,
- transcludeDirective = previousCompileContext.transcludeDirective,
replaceDirective = originalReplaceDirective,
childTranscludeFn = transcludeFn,
- controllerDirectives,
linkFn,
directiveValue;
@@ -1191,9 +1191,10 @@ function $CompileProvider($provide) {
childTranscludeFn = compile($template, transcludeFn, terminalPriority,
replaceDirective && replaceDirective.name, {
+ controllerDirectives: controllerDirectives,
newIsolateScopeDirective: newIsolateScopeDirective,
- transcludeDirective: transcludeDirective,
- templateDirective: templateDirective
+ templateDirective: templateDirective,
+ transcludeDirective: transcludeDirective
});
} else {
$template = jqLite(jqLiteClone(compileNode)).contents();
@@ -1259,9 +1260,10 @@ function $CompileProvider($provide) {
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, {
+ controllerDirectives: controllerDirectives,
newIsolateScopeDirective: newIsolateScopeDirective,
- transcludeDirective: transcludeDirective,
- templateDirective: templateDirective
+ templateDirective: templateDirective,
+ transcludeDirective: transcludeDirective
});
ii = directives.length;
} else if (directive.compile) {
@@ -1415,7 +1417,7 @@ function $CompileProvider($provide) {
return parentGet(parentScope, locals);
};
break;
-
+
default:
throw $compileMinErr('iscp',
"Invalid isolate scope definition for directive '{0}'." +
@@ -1819,7 +1821,7 @@ function directiveNormalize(name) {
/**
* @ngdoc object
* @name ng.$compile.directive.Attributes
- *
+ *
* @description
* A shared object between directive compile / linking functions which contains normalized DOM
* element attributes. The the values reflect current binding state `{{ }}`. The normalization is
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index 9a69824a..0bba6b37 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -2282,6 +2282,60 @@ describe('$compile', function() {
});
+ it('should get required controller via linkingFn (template)', function() {
+ module(function() {
+ directive('dirA', function() {
+ return {
+ controller: function() {
+ this.name = 'dirA';
+ }
+ };
+ });
+ directive('dirB', function(log) {
+ return {
+ require: 'dirA',
+ template: '<p>dirB</p>',
+ link: function(scope, element, attrs, dirAController) {
+ log('dirAController.name: ' + dirAController.name);
+ }
+ };
+ });
+ });
+ inject(function(log, $compile, $rootScope) {
+ element = $compile('<div dir-a dir-b></div>')($rootScope);
+ expect(log).toEqual('dirAController.name: dirA');
+ });
+ });
+
+
+ it('should get required controller via linkingFn (templateUrl)', function() {
+ module(function() {
+ directive('dirA', function() {
+ return {
+ controller: function() {
+ this.name = 'dirA';
+ }
+ };
+ });
+ directive('dirB', function(log) {
+ return {
+ require: 'dirA',
+ templateUrl: 'dirB.html',
+ link: function(scope, element, attrs, dirAController) {
+ log('dirAController.name: ' + dirAController.name);
+ }
+ };
+ });
+ });
+ inject(function(log, $compile, $rootScope, $templateCache) {
+ $templateCache.put('dirB.html', '<p>dirB</p>');
+ element = $compile('<div dir-a dir-b></div>')($rootScope);
+ $rootScope.$digest();
+ expect(log).toEqual('dirAController.name: dirA');
+ });
+ });
+
+
it('should support controllerAs', function() {
module(function() {
directive('main', function() {