mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
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
This commit is contained in:
parent
e57d5b89ca
commit
faf5b980da
2 changed files with 64 additions and 8 deletions
|
|
@ -1117,16 +1117,16 @@ function $CompileProvider($provide) {
|
||||||
|
|
||||||
var terminalPriority = -Number.MAX_VALUE,
|
var terminalPriority = -Number.MAX_VALUE,
|
||||||
newScopeDirective,
|
newScopeDirective,
|
||||||
|
controllerDirectives = previousCompileContext.controllerDirectives,
|
||||||
newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
|
newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
|
||||||
templateDirective = previousCompileContext.templateDirective,
|
templateDirective = previousCompileContext.templateDirective,
|
||||||
|
transcludeDirective = previousCompileContext.transcludeDirective,
|
||||||
$compileNode = templateAttrs.$$element = jqLite(compileNode),
|
$compileNode = templateAttrs.$$element = jqLite(compileNode),
|
||||||
directive,
|
directive,
|
||||||
directiveName,
|
directiveName,
|
||||||
$template,
|
$template,
|
||||||
transcludeDirective = previousCompileContext.transcludeDirective,
|
|
||||||
replaceDirective = originalReplaceDirective,
|
replaceDirective = originalReplaceDirective,
|
||||||
childTranscludeFn = transcludeFn,
|
childTranscludeFn = transcludeFn,
|
||||||
controllerDirectives,
|
|
||||||
linkFn,
|
linkFn,
|
||||||
directiveValue;
|
directiveValue;
|
||||||
|
|
||||||
|
|
@ -1191,9 +1191,10 @@ function $CompileProvider($provide) {
|
||||||
|
|
||||||
childTranscludeFn = compile($template, transcludeFn, terminalPriority,
|
childTranscludeFn = compile($template, transcludeFn, terminalPriority,
|
||||||
replaceDirective && replaceDirective.name, {
|
replaceDirective && replaceDirective.name, {
|
||||||
|
controllerDirectives: controllerDirectives,
|
||||||
newIsolateScopeDirective: newIsolateScopeDirective,
|
newIsolateScopeDirective: newIsolateScopeDirective,
|
||||||
transcludeDirective: transcludeDirective,
|
templateDirective: templateDirective,
|
||||||
templateDirective: templateDirective
|
transcludeDirective: transcludeDirective
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$template = jqLite(jqLiteClone(compileNode)).contents();
|
$template = jqLite(jqLiteClone(compileNode)).contents();
|
||||||
|
|
@ -1259,9 +1260,10 @@ function $CompileProvider($provide) {
|
||||||
|
|
||||||
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
|
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
|
||||||
templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, {
|
templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, {
|
||||||
|
controllerDirectives: controllerDirectives,
|
||||||
newIsolateScopeDirective: newIsolateScopeDirective,
|
newIsolateScopeDirective: newIsolateScopeDirective,
|
||||||
transcludeDirective: transcludeDirective,
|
templateDirective: templateDirective,
|
||||||
templateDirective: templateDirective
|
transcludeDirective: transcludeDirective
|
||||||
});
|
});
|
||||||
ii = directives.length;
|
ii = directives.length;
|
||||||
} else if (directive.compile) {
|
} else if (directive.compile) {
|
||||||
|
|
@ -1415,7 +1417,7 @@ function $CompileProvider($provide) {
|
||||||
return parentGet(parentScope, locals);
|
return parentGet(parentScope, locals);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw $compileMinErr('iscp',
|
throw $compileMinErr('iscp',
|
||||||
"Invalid isolate scope definition for directive '{0}'." +
|
"Invalid isolate scope definition for directive '{0}'." +
|
||||||
|
|
@ -1819,7 +1821,7 @@ function directiveNormalize(name) {
|
||||||
/**
|
/**
|
||||||
* @ngdoc object
|
* @ngdoc object
|
||||||
* @name ng.$compile.directive.Attributes
|
* @name ng.$compile.directive.Attributes
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* A shared object between directive compile / linking functions which contains normalized DOM
|
* A shared object between directive compile / linking functions which contains normalized DOM
|
||||||
* element attributes. The the values reflect current binding state `{{ }}`. The normalization is
|
* element attributes. The the values reflect current binding state `{{ }}`. The normalization is
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
it('should support controllerAs', function() {
|
||||||
module(function() {
|
module(function() {
|
||||||
directive('main', function() {
|
directive('main', function() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue