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

Commit

Permalink
fix($compile): instantiate controlers when re-entering compilation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
IgorMinar committed Oct 24, 2013
1 parent e57d5b8 commit faf5b98
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 8 deletions.
18 changes: 10 additions & 8 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1415,7 +1417,7 @@ function $CompileProvider($provide) {
return parentGet(parentScope, locals);
};
break;

default:
throw $compileMinErr('iscp',
"Invalid isolate scope definition for directive '{0}'." +
Expand Down Expand Up @@ -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
Expand Down
54 changes: 54 additions & 0 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit faf5b98

Please sign in to comment.