fix($compile): remove the preAssignBindingsEnabled flag
Closes #15782 BREAKING CHANGE: Previously, the `$compileProvider.preAssignBindingsEnabled` flag was supported. The flag controlled whether bindings were available inside the controller constructor or only in the `$onInit` hook. The bindings are now no longer available in the constructor. To migrate your code: 1. If you haven't invoked `$compileProvider.preAssignBindingsEnabled()` you don't have to do anything to migrate. 2. If you specified `$compileProvider.preAssignBindingsEnabled(false)`, you can remove that statement - since AngularJS 1.6.0 this is the default so your app should still work even in AngularJS 1.6 after such removal. Afterwards, migrating to AngularJS 1.7.0 shouldn't require any further action. 3. If you specified `$compileProvider.preAssignBindingsEnabled(true)` you need to first migrate your code so that the flag can be flipped to `false`. The instructions on how to do that are available in the "Migrating from 1.5 to 1.6" guide: https://docs.angularjs.org/guide/migration#migrating-from-1-5-to-1-6 Afterwards, remove the `$compileProvider.preAssignBindingsEnabled(true)` statement.
This commit is contained in:
+4
-56
@@ -1372,36 +1372,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
return debugInfoEnabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $compileProvider#preAssignBindingsEnabled
|
||||
*
|
||||
* @param {boolean=} enabled update the preAssignBindingsEnabled state if provided, otherwise just return the
|
||||
* current preAssignBindingsEnabled state
|
||||
* @returns {*} current value if used as getter or itself (chaining) if used as setter
|
||||
*
|
||||
* @kind function
|
||||
*
|
||||
* @description
|
||||
* Call this method to enable/disable whether directive controllers are assigned bindings before
|
||||
* calling the controller's constructor.
|
||||
* If enabled (true), the compiler assigns the value of each of the bindings to the
|
||||
* properties of the controller object before the constructor of this object is called.
|
||||
*
|
||||
* If disabled (false), the compiler calls the constructor first before assigning bindings.
|
||||
*
|
||||
* The default value is true in AngularJS 1.5.x but will switch to false in AngularJS 1.6.x.
|
||||
*/
|
||||
var preAssignBindingsEnabled = false;
|
||||
this.preAssignBindingsEnabled = function(enabled) {
|
||||
if (isDefined(enabled)) {
|
||||
preAssignBindingsEnabled = enabled;
|
||||
return this;
|
||||
}
|
||||
return preAssignBindingsEnabled;
|
||||
};
|
||||
|
||||
|
||||
var TTL = 10;
|
||||
/**
|
||||
* @ngdoc method
|
||||
@@ -2722,33 +2692,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
var controller = elementControllers[name];
|
||||
var bindings = controllerDirective.$$bindings.bindToController;
|
||||
|
||||
if (preAssignBindingsEnabled) {
|
||||
if (bindings) {
|
||||
controller.bindingInfo =
|
||||
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
|
||||
} else {
|
||||
controller.bindingInfo = {};
|
||||
}
|
||||
|
||||
var controllerResult = controller();
|
||||
if (controllerResult !== controller.instance) {
|
||||
// If the controller constructor has a return value, overwrite the instance
|
||||
// from setupControllers
|
||||
controller.instance = controllerResult;
|
||||
$element.data('$' + controllerDirective.name + 'Controller', controllerResult);
|
||||
if (controller.bindingInfo.removeWatches) {
|
||||
controller.bindingInfo.removeWatches();
|
||||
}
|
||||
controller.bindingInfo =
|
||||
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
|
||||
}
|
||||
} else {
|
||||
controller.instance = controller();
|
||||
$element.data('$' + controllerDirective.name + 'Controller', controller.instance);
|
||||
controller.bindingInfo =
|
||||
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
|
||||
controller.instance = controller();
|
||||
$element.data('$' + controllerDirective.name + 'Controller', controller.instance);
|
||||
controller.bindingInfo =
|
||||
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
|
||||
forEach(controllerDirectives, function(controllerDirective, name) {
|
||||
|
||||
Vendored
+2
-16
@@ -2207,11 +2207,6 @@ angular.mock.$RootElementProvider = function() {
|
||||
* A decorator for {@link ng.$controller} with additional `bindings` parameter, useful when testing
|
||||
* controllers of directives that use {@link $compile#-bindtocontroller- `bindToController`}.
|
||||
*
|
||||
* Depending on the value of
|
||||
* {@link ng.$compileProvider#preAssignBindingsEnabled `preAssignBindingsEnabled()`}, the properties
|
||||
* will be bound before or after invoking the constructor.
|
||||
*
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```js
|
||||
@@ -2267,22 +2262,13 @@ angular.mock.$RootElementProvider = function() {
|
||||
* the `bindToController` feature and simplify certain kinds of tests.
|
||||
* @return {Object} Instance of given controller.
|
||||
*/
|
||||
function createControllerDecorator(compileProvider) {
|
||||
function createControllerDecorator() {
|
||||
angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
|
||||
return function(expression, locals, later, ident) {
|
||||
if (later && typeof later === 'object') {
|
||||
var preAssignBindingsEnabled = compileProvider.preAssignBindingsEnabled();
|
||||
|
||||
var instantiate = $delegate(expression, locals, true, ident);
|
||||
if (preAssignBindingsEnabled) {
|
||||
angular.extend(instantiate.instance, later);
|
||||
}
|
||||
|
||||
var instance = instantiate();
|
||||
if (!preAssignBindingsEnabled || instance !== instantiate.instance) {
|
||||
angular.extend(instance, later);
|
||||
}
|
||||
|
||||
angular.extend(instance, later);
|
||||
return instance;
|
||||
}
|
||||
return $delegate(expression, locals, later, ident);
|
||||
|
||||
+6283
-6406
File diff suppressed because it is too large
Load Diff
Vendored
+42
-125
@@ -2039,89 +2039,29 @@ describe('ngMock', function() {
|
||||
|
||||
describe('$controllerDecorator', function() {
|
||||
|
||||
describe('with `preAssignBindingsEnabled(true)`', function() {
|
||||
|
||||
beforeEach(module(function($compileProvider) {
|
||||
$compileProvider.preAssignBindingsEnabled(true);
|
||||
}));
|
||||
|
||||
|
||||
it('should support creating controller with bindings', function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
{ name: 'testname', id: 1 },
|
||||
{ name: 'flurp', id: 2 }
|
||||
];
|
||||
module(function($controllerProvider) {
|
||||
$controllerProvider.register('testCtrl', function() {
|
||||
expect(this.data).toBe(data);
|
||||
called = true;
|
||||
});
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
it('should support creating controller with bindings', function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
{ name: 'testname', id: 1 },
|
||||
{ name: 'flurp', id: 2 }
|
||||
];
|
||||
module(function($controllerProvider) {
|
||||
$controllerProvider.register('testCtrl', function() {
|
||||
expect(this.data).toBeUndefined();
|
||||
called = true;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should support assigning bindings when a value is returned from the constructor',
|
||||
function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
{ name: 'testname', id: 1 },
|
||||
{ name: 'flurp', id: 2 }
|
||||
];
|
||||
module(function($controllerProvider) {
|
||||
$controllerProvider.register('testCtrl', function() {
|
||||
expect(this.data).toBe(data);
|
||||
called = true;
|
||||
return {};
|
||||
});
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
if (/chrome/.test(window.navigator.userAgent)) {
|
||||
it('should support assigning bindings to class-based controller', function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
{ name: 'testname', id: 1 },
|
||||
{ name: 'flurp', id: 2 }
|
||||
];
|
||||
module(function($controllerProvider) {
|
||||
// eslint-disable-next-line no-eval
|
||||
var TestCtrl = eval('(class { constructor() { called = true; } })');
|
||||
$controllerProvider.register('testCtrl', TestCtrl);
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
inject(function($controller, $rootScope) {
|
||||
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('with `preAssignBindingsEnabled(false)`', function() {
|
||||
|
||||
beforeEach(module(function($compileProvider) {
|
||||
$compileProvider.preAssignBindingsEnabled(false);
|
||||
}));
|
||||
|
||||
|
||||
it('should support creating controller with bindings', function() {
|
||||
it('should support assigning bindings when a value is returned from the constructor',
|
||||
function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
@@ -2132,6 +2072,7 @@ describe('ngMock', function() {
|
||||
$controllerProvider.register('testCtrl', function() {
|
||||
expect(this.data).toBeUndefined();
|
||||
called = true;
|
||||
return {};
|
||||
});
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
@@ -2139,54 +2080,30 @@ describe('ngMock', function() {
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should support assigning bindings when a value is returned from the constructor',
|
||||
function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
{ name: 'testname', id: 1 },
|
||||
{ name: 'flurp', id: 2 }
|
||||
];
|
||||
module(function($controllerProvider) {
|
||||
$controllerProvider.register('testCtrl', function() {
|
||||
expect(this.data).toBeUndefined();
|
||||
called = true;
|
||||
return {};
|
||||
});
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
if (/chrome/.test(window.navigator.userAgent)) {
|
||||
it('should support assigning bindings to class-based controller', function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
{ name: 'testname', id: 1 },
|
||||
{ name: 'flurp', id: 2 }
|
||||
];
|
||||
module(function($controllerProvider) {
|
||||
// eslint-disable-next-line no-eval
|
||||
var TestCtrl = eval('(class { constructor() { called = true; } })');
|
||||
$controllerProvider.register('testCtrl', TestCtrl);
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
|
||||
if (/chrome/.test(window.navigator.userAgent)) {
|
||||
it('should support assigning bindings to class-based controller', function() {
|
||||
var called = false;
|
||||
var data = [
|
||||
{ name: 'derp1', id: 0 },
|
||||
{ name: 'testname', id: 1 },
|
||||
{ name: 'flurp', id: 2 }
|
||||
];
|
||||
module(function($controllerProvider) {
|
||||
// eslint-disable-next-line no-eval
|
||||
var TestCtrl = eval('(class { constructor() { called = true; } })');
|
||||
$controllerProvider.register('testCtrl', TestCtrl);
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
var ctrl = $controller('testCtrl', { scope: $rootScope }, { data: data });
|
||||
expect(ctrl.data).toBe(data);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user