Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 719e95e

Browse files
committed
fix(ngMock#$controller): properly assign bindings to all types of controllers (e.g. class-based)
The decorated version of `$controller` is able to assign bindings to a controller instance prior to instantiation, emulating the behavior of `$compile` with directive controllers. There are cases, that the actual controller instance is different than the pre-populated one (e.g. when the controller constructor function returns a value or when the controller is an ES2015 Class). While `$compile` accounts for such situation, by re-asigning the bindings after the controller has been instantiated, `ngMock`'s `$controller` didn't. This commit fixes it, by re-applying the bindings if the actual controller instance is different than the original one (similar to how `$compile` would do it). Fixes #14437
1 parent c4fb0ec commit 719e95e

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

src/ngMock/angular-mocks.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -2181,9 +2181,15 @@ angular.mock.$RootElementProvider = function() {
21812181
angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
21822182
return function(expression, locals, later, ident) {
21832183
if (later && typeof later === 'object') {
2184-
var create = $delegate(expression, locals, true, ident);
2185-
angular.extend(create.instance, later);
2186-
return create();
2184+
var instantiate = $delegate(expression, locals, true, ident);
2185+
angular.extend(instantiate.instance, later);
2186+
2187+
var instance = instantiate();
2188+
if (instance !== instantiate.instance) {
2189+
angular.extend(instance, later);
2190+
}
2191+
2192+
return instance;
21872193
}
21882194
return $delegate(expression, locals, later, ident);
21892195
};

test/ngMock/angular-mocksSpec.js

+49
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict';
22

3+
/* globals support: false */
4+
35
describe('ngMock', function() {
46
var noop = angular.noop;
57

@@ -1888,6 +1890,53 @@ describe('ngMock', function() {
18881890
expect(called).toBe(true);
18891891
});
18901892
});
1893+
1894+
it('should support assigning bindings when a value is returned from the constructor',
1895+
function() {
1896+
var called = false;
1897+
var data = [
1898+
{ name: 'derp1', id: 0 },
1899+
{ name: 'testname', id: 1 },
1900+
{ name: 'flurp', id: 2 }
1901+
];
1902+
module(function($controllerProvider) {
1903+
$controllerProvider.register('testCtrl', function() {
1904+
called = true;
1905+
expect(this.data).toBe(data);
1906+
1907+
return {};
1908+
});
1909+
});
1910+
inject(function($controller, $rootScope) {
1911+
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
1912+
expect(ctrl.data).toBe(data);
1913+
expect(called).toBe(true);
1914+
});
1915+
}
1916+
);
1917+
1918+
if (support.classes) {
1919+
it('should support assigning bindings to class-based controller', function() {
1920+
var called = false;
1921+
var data = [
1922+
{ name: 'derp1', id: 0 },
1923+
{ name: 'testname', id: 1 },
1924+
{ name: 'flurp', id: 2 }
1925+
];
1926+
module(function($controllerProvider) {
1927+
$controllerProvider.register('testCtrl', class TextCtrl {
1928+
constructor() {
1929+
called = true;
1930+
}
1931+
});
1932+
});
1933+
inject(function($controller, $rootScope) {
1934+
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
1935+
expect(ctrl.data).toBe(data);
1936+
expect(called).toBe(true);
1937+
});
1938+
});
1939+
}
18911940
});
18921941

18931942

0 commit comments

Comments
 (0)