Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 33f817b

Browse files
feat($componentController): provide isolated scope if none is passed (angular#14425)
Closes angular#14425
1 parent 6a4124d commit 33f817b

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

src/ngMock/angular-mocks.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,8 +2195,8 @@ angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
21952195
* A service that can be used to create instances of component controllers.
21962196
* <div class="alert alert-info">
21972197
* Be aware that the controller will be instantiated and attached to the scope as specified in
2198-
* the component definition object. That means that you must always provide a `$scope` object
2199-
* in the `locals` param.
2198+
* the component definition object. If you do not provide a `$scope` object in the `locals` param
2199+
* then the helper will create a new isolated scope as a child of `$rootScope`.
22002200
* </div>
22012201
* @param {string} componentName the name of the component whose controller we want to instantiate
22022202
* @param {Object} locals Injection locals for Controller.
@@ -2206,7 +2206,7 @@ angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
22062206
* @return {Object} Instance of requested controller.
22072207
*/
22082208
angular.mock.$ComponentControllerProvider = ['$compileProvider', function($compileProvider) {
2209-
this.$get = ['$controller','$injector', function($controller,$injector) {
2209+
this.$get = ['$controller','$injector', '$rootScope', function($controller, $injector, $rootScope) {
22102210
return function $componentController(componentName, locals, bindings, ident) {
22112211
// get all directives associated to the component name
22122212
var directives = $injector.get(componentName + 'Directive');
@@ -2224,6 +2224,9 @@ angular.mock.$ComponentControllerProvider = ['$compileProvider', function($compi
22242224
}
22252225
// get the info of the component
22262226
var directiveInfo = candidateDirectives[0];
2227+
// create a scope if needed
2228+
locals = locals || {};
2229+
locals.$scope = locals.$scope || $rootScope.$new(true);
22272230
return $controller(directiveInfo.controller, locals, bindings, ident || directiveInfo.controllerAs);
22282231
};
22292232
}];

test/ngMock/angular-mocksSpec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,27 @@ describe('ngMock', function() {
20892089
}).toThrowError('Too many components found');
20902090
});
20912091
});
2092+
2093+
it('should create an isolated child of $rootScope, if no `$scope` local is provided', function() {
2094+
function TestController($scope) {
2095+
this.$scope = $scope;
2096+
}
2097+
module(function($compileProvider) {
2098+
$compileProvider.component('test', {
2099+
controller: TestController
2100+
});
2101+
});
2102+
inject(function($componentController, $rootScope) {
2103+
var $ctrl = $componentController('test');
2104+
expect($ctrl.$scope).toBeDefined();
2105+
expect($ctrl.$scope.$parent).toBe($rootScope);
2106+
// check it is isolated
2107+
$rootScope.a = 17;
2108+
expect($ctrl.$scope.a).toBeUndefined();
2109+
$ctrl.$scope.a = 42;
2110+
expect($rootScope.a).toEqual(17);
2111+
});
2112+
});
20922113
});
20932114
});
20942115

0 commit comments

Comments
 (0)