fix($compile): set $isolateScope correctly for sync template directives

All isolated scope directives that do not have `templateUrl` were marked
as `$isolateScopeNoTemplate` even if they did have a `template` attribute.

This caused `jqLite#scope()` to return the wrong value for child elements
within the directive's template.

Closes #6942
This commit is contained in:
Shahar Talmi
2014-04-01 23:40:10 +03:00
committed by Peter Bacon Darwin
parent a0ae07bd4e
commit 562c4e424b
2 changed files with 55 additions and 1 deletions

View File

@@ -1425,7 +1425,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
isolateScope = scope.$new(true);
if (templateDirective && (templateDirective === newIsolateScopeDirective.$$originalDirective)) {
if (templateDirective && (templateDirective === newIsolateScopeDirective ||
templateDirective === newIsolateScopeDirective.$$originalDirective)) {
$linkNode.data('$isolateScope', isolateScope) ;
} else {
$linkNode.data('$isolateScopeNoTemplate', isolateScope);

View File

@@ -1797,6 +1797,19 @@ describe('$compile', function() {
}
};
});
directive('stscope' + uppercase(name), function(log) {
return {
scope: true,
restrict: 'CA',
template: '<span></span>',
compile: function() {
return function (scope, element) {
log(scope.$id);
expect(element.data('$scope')).toBe(scope);
};
}
};
});
directive('trscope' + uppercase(name), function(log) {
return {
scope: true,
@@ -1825,6 +1838,20 @@ describe('$compile', function() {
}
};
});
directive('stiscope' + uppercase(name), function(log) {
return {
scope: {},
restrict: 'CA',
template: '<span></span>',
compile: function() {
return function (scope, element) {
iscope = scope;
log(scope.$id);
expect(element.data('$isolateScope')).toBe(scope);
};
}
};
});
});
directive('log', function(log) {
return {
@@ -1999,6 +2026,13 @@ describe('$compile', function() {
expect(element.find('a').scope().$parent).toBe($rootScope);
})
);
it('should return the new scope for children in the directive sync template', inject(
function($rootScope, $compile) {
element = $compile('<div stscope></div>')($rootScope);
expect(element.find('span').scope().$parent).toBe($rootScope);
})
);
});
@@ -2041,6 +2075,14 @@ describe('$compile', function() {
expect(element.isolateScope()).not.toBe($rootScope);
})
);
it('should return the isolate scope for children in directive sync template', inject(
function($rootScope, $compile) {
element = $compile('<div stiscope></div>')($rootScope);
expect(element.find('span').scope()).toBe(element.isolateScope());
expect(element.isolateScope()).not.toBe($rootScope);
})
);
});
@@ -2070,6 +2112,17 @@ describe('$compile', function() {
expect(child.scope()).toBe(directiveElement.isolateScope());
})
);
it('should return the isolate scope for child elements in directive sync template', inject(
function($rootScope, $compile) {
var directiveElement, child;
element = $compile('<div><a ng-if="true" stiscope></a></div>')($rootScope);
$rootScope.$apply();
directiveElement = element.find('a');
child = directiveElement.find('span');
expect(child.scope()).toBe(directiveElement.isolateScope());
})
);
});
});
});