aboutsummaryrefslogtreecommitdiffstats
path: root/test/ng/compileSpec.js
diff options
context:
space:
mode:
authorVojta Jina2013-11-05 12:31:20 -0800
committerIgor Minar2013-11-07 22:03:19 -0800
commit909cabd36d779598763cc358979ecd85bb40d4d7 (patch)
tree3f59a30dc5c44df46a86af249b0538272b47c555 /test/ng/compileSpec.js
parent36621402015485613888158dc7ba29f4ff92a7e2 (diff)
downloadangular.js-909cabd36d779598763cc358979ecd85bb40d4d7.tar.bz2
fix($compile): make isolate scope truly isolate
Fixes issue with isolate scope leaking all over the place into other directives on the same element. Isolate scope is now available only to the isolate directive that requested it and its template. A non-isolate directive should not get the isolate scope of an isolate directive on the same element, instead they will receive the original scope (which is the parent scope of the newly created isolate scope). Paired with Tobias. BREAKING CHANGE: Directives without isolate scope do not get the isolate scope from an isolate directive on the same element. If your code depends on this behavior (non-isolate directive needs to access state from within the isolate scope), change the isolate directive to use scope locals to pass these explicitly. // before <input ng-model="$parent.value" ng-isolate> .directive('ngIsolate', function() { return { scope: {}, template: '{{value}}' }; }); // after <input ng-model="value" ng-isolate> .directive('ngIsolate', function() { return { scope: {value: '=ngModel'}, template: '{{value}} }; }); Closes #1924 Closes #2500
Diffstat (limited to 'test/ng/compileSpec.js')
-rwxr-xr-xtest/ng/compileSpec.js87
1 files changed, 83 insertions, 4 deletions
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index c6cba3a4..09048885 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -1375,7 +1375,7 @@ describe('$compile', function() {
return function (scope, element) {
iscope = scope;
log(scope.$id);
- expect(element.data('$scope')).toBe(scope);
+ expect(element.data('$isolateScope')).toBe(scope);
};
}
};
@@ -1416,7 +1416,7 @@ describe('$compile', function() {
return function (scope, element) {
iscope = scope;
log(scope.$id);
- expect(element.data('$scope')).toBe(scope);
+ expect(element.data('$isolateScope')).toBe(scope);
};
}
};
@@ -1535,7 +1535,7 @@ describe('$compile', function() {
expect(function(){
$compile('<div class="iscope-a; scope-b"></div>');
}).toThrowMinErr('$compile', 'multidir', 'Multiple directives [iscopeA, scopeB] asking for new/isolated scope on: ' +
- '<div class="iscope-a; scope-b ng-isolate-scope ng-scope">');
+ '<div class="iscope-a; scope-b">');
})
);
@@ -2085,7 +2085,7 @@ describe('$compile', function() {
describe('isolated locals', function() {
- var componentScope;
+ var componentScope, regularScope;
beforeEach(module(function() {
directive('myComponent', function() {
@@ -2112,6 +2112,23 @@ describe('$compile', function() {
scope: { attr: 'xxx' }
};
});
+ directive('storeScope', function() {
+ return {
+ link: function(scope) {
+ regularScope = scope;
+ }
+ }
+ });
+ }));
+
+ it('should give other directives the parent scope', inject(function($rootScope) {
+ compile('<div><input type="text" my-component store-scope ng-model="value"></div>');
+ $rootScope.$apply(function() {
+ $rootScope.value = 'from-parent';
+ });
+ expect(element.find('input').val()).toBe('from-parent');
+ expect(componentScope).not.toBe(regularScope);
+ expect(componentScope.$parent).toBe(regularScope)
}));
describe('attribute', function() {
@@ -2376,6 +2393,68 @@ describe('$compile', function() {
});
+ it('should require controller of an isolate directive from a non-isolate directive on the ' +
+ 'same element', function() {
+ var IsolateController = function() {};
+ var isolateDirControllerInNonIsolateDirective;
+
+ module(function() {
+ directive('isolate', function() {
+ return {
+ scope: {},
+ controller: IsolateController
+ };
+ });
+ directive('nonIsolate', function() {
+ return {
+ require: 'isolate',
+ link: function(_, __, ___, isolateDirController) {
+ isolateDirControllerInNonIsolateDirective = isolateDirController;
+ }
+ };
+ });
+ });
+
+ inject(function($compile, $rootScope) {
+ element = $compile('<div isolate non-isolate></div>')($rootScope);
+
+ expect(isolateDirControllerInNonIsolateDirective).toBeDefined();
+ expect(isolateDirControllerInNonIsolateDirective instanceof IsolateController).toBe(true);
+ });
+ });
+
+
+ it('should require controller of a non-isolate directive from an isolate directive on the ' +
+ 'same element', function() {
+ var NonIsolateController = function() {};
+ var nonIsolateDirControllerInIsolateDirective;
+
+ module(function() {
+ directive('isolate', function() {
+ return {
+ scope: {},
+ require: 'nonIsolate',
+ link: function(_, __, ___, nonIsolateDirController) {
+ nonIsolateDirControllerInIsolateDirective = nonIsolateDirController;
+ }
+ };
+ });
+ directive('nonIsolate', function() {
+ return {
+ controller: NonIsolateController
+ };
+ });
+ });
+
+ inject(function($compile, $rootScope) {
+ element = $compile('<div isolate non-isolate></div>')($rootScope);
+
+ expect(nonIsolateDirControllerInIsolateDirective).toBeDefined();
+ expect(nonIsolateDirControllerInIsolateDirective instanceof NonIsolateController).toBe(true);
+ });
+ });
+
+
it('should support controllerAs', function() {
module(function() {
directive('main', function() {