mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix($compile): don't leak isolate scope state when replaced directive is used multiple times
When an isolate scope directive is also a "replace" directive and at the root of its template it has other directives, we need to keep track remember to use isolate scope when linking these. This commit fixes the leakage of this state when this directive is used again later inside or outside of the isolate directive template.
This commit is contained in:
parent
3fe4491a6b
commit
b5af198f0d
2 changed files with 48 additions and 4 deletions
|
|
@ -1303,13 +1303,17 @@ function $CompileProvider($provide) {
|
|||
if (pre) {
|
||||
if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
|
||||
pre.require = directive.require;
|
||||
if (newIsolateScopeDirective === directive || directive.$$isolateScope) pre.isolateScope = true;
|
||||
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
|
||||
pre = cloneAndAnnotateFn(pre, {isolateScope: true});
|
||||
}
|
||||
preLinkFns.push(pre);
|
||||
}
|
||||
if (post) {
|
||||
if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
|
||||
post.require = directive.require;
|
||||
if (newIsolateScopeDirective === directive || directive.$$isolateScope) post.isolateScope = true;
|
||||
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
|
||||
post = cloneAndAnnotateFn(post, {isolateScope: true});
|
||||
}
|
||||
postLinkFns.push(post);
|
||||
}
|
||||
}
|
||||
|
|
@ -1830,6 +1834,11 @@ function $CompileProvider($provide) {
|
|||
elementsToRemove[0] = newNode;
|
||||
elementsToRemove.length = 1;
|
||||
}
|
||||
|
||||
|
||||
function cloneAndAnnotateFn(fn, annotation) {
|
||||
return extend(function() { return fn.apply(null, arguments); }, fn, annotation);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2504,7 +2504,7 @@ describe('$compile', function() {
|
|||
});
|
||||
|
||||
|
||||
it('should share isolate scope with replaced directives', function() {
|
||||
it('should share isolate scope with replaced directives (template)', function() {
|
||||
var normalScope;
|
||||
var isolateScope;
|
||||
|
||||
|
|
@ -2540,7 +2540,7 @@ describe('$compile', function() {
|
|||
});
|
||||
|
||||
|
||||
it('should share isolate scope with replaced directives', function() {
|
||||
it('should share isolate scope with replaced directives (templateUrl)', function() {
|
||||
var normalScope;
|
||||
var isolateScope;
|
||||
|
||||
|
|
@ -2577,6 +2577,41 @@ describe('$compile', function() {
|
|||
});
|
||||
|
||||
|
||||
it('should not get confused about where to use isolate scope when a replaced directive is used multiple times',
|
||||
function() {
|
||||
|
||||
module(function() {
|
||||
directive('isolate', function() {
|
||||
return {
|
||||
replace: true,
|
||||
scope: {},
|
||||
template: '<span scope-tester="replaced"><span scope-tester="inside"></span></span>'
|
||||
};
|
||||
});
|
||||
directive('scopeTester', function(log) {
|
||||
return {
|
||||
link: function($scope, $element) {
|
||||
log($element.attr('scope-tester') + '=' + ($scope.$root === $scope ? 'non-isolate' : 'isolate'));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
inject(function($compile, $rootScope, log) {
|
||||
element = $compile('<div>' +
|
||||
'<div isolate scope-tester="outside"></div>' +
|
||||
'<span scope-tester="sibling"></span>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('inside=isolate; ' +
|
||||
'outside replaced=non-isolate; ' + // outside
|
||||
'outside replaced=isolate; ' + // replaced
|
||||
'sibling=non-isolate')
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should require controller of a non-isolate directive from an isolate directive on the ' +
|
||||
'same element', function() {
|
||||
var NonIsolateController = function() {};
|
||||
|
|
|
|||
Loading…
Reference in a new issue