-
Notifications
You must be signed in to change notification settings - Fork 3.4k
fix(compiler): respect preAssignBindingsEnabled state #10469
Conversation
@devversion - Think this one of my favorite PRs for Q1 2017. 🥇 |
The Karma not logging issue is a regression: karma-runner/karma#2582. How about locking Karma to 1.4 for now as it's not clear for now how they will resolve the issue and removing the workaround? |
$provide.constant('$$mdPreAssignBindings', | ||
// For Angular versions that do not support `preAssignBindingsEnabled`, always pre-assign the | ||
// bindings. | ||
$compileProvider.preAssignBindingsEnabled ? $compileProvider.preAssignBindingsEnabled() : true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure the $compileProvider.preAssignBindingsEnabled()
output is set in stone at this point?
Also, note that AngularJS 1.7 will remove $compileProvider.preAssignBindingsEnabled
and the bindings will stop being pre-assigned so this code is not future-proof.
If the method is not present, it's safer to check the library version and set true
only if it's older than 1.6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure the
$compileProvider.preAssignBindingsEnabled()
output is set in stone at this point?
As a matter of fact, it is never set in stone 😁 (you can change it any time). Not that this is a common usecase.
.provider('$$mdPreAssignBindings', function ($compileProvider) {
var hardcodedValue = (angular.version.major === 1 && angular.version.minor < 6) ? true : false;
var getValue = $compileProvider.preAssignBindingsEnabled ?
function () { $compileProvider.preAssignBindingsEnabled(); } :
function () { return hardcodedValue; };
this.$get = function () { return getValue; };
})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uugh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkalpak your implementation is good, I'd just drop the ? true : false
part as it's redundant here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do this true/false
thing too often 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 💯
$provide.constant('$$mdPreAssignBindings', | ||
// For Angular versions that do not support `preAssignBindingsEnabled`, always pre-assign the | ||
// bindings. | ||
$compileProvider.preAssignBindingsEnabled ? $compileProvider.preAssignBindingsEnabled() : true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure the
$compileProvider.preAssignBindingsEnabled()
output is set in stone at this point?
As a matter of fact, it is never set in stone 😁 (you can change it any time). Not that this is a common usecase.
.provider('$$mdPreAssignBindings', function ($compileProvider) {
var hardcodedValue = (angular.version.major === 1 && angular.version.minor < 6) ? true : false;
var getValue = $compileProvider.preAssignBindingsEnabled ?
function () { $compileProvider.preAssignBindingsEnabled(); } :
function () { return hardcodedValue; };
this.$get = function () { return getValue; };
})
|
||
var ctrl = invokeCtrl(); | ||
// Create the specified controller instance. | ||
var ctrl = self._createController(options, injectLocals); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not directly related to this PR, but it seems that you are accidentally putting $element
into locals
. Essentially, locals
and injectLocals
are the same object, but this doesn't seem intentional (and indeed assigning $element
to the controller instance seems strange).
Was it intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
} | ||
|
||
TestController.prototype.$onInit = function() { | ||
expect(this.name).toBe('Bob'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no verification that $onInit()
is actually called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, for the constructor you check that called
has been set to true, so you know that the constructor has been called (and the expectations it contains verified).
There is nothing similar for $onInit()
.
You could add expect('foo').toBe('bar')
inside $onInit()
and the test would not fail if $onInit()
is never called. This means that the test may not catch some future regression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's why I like QUnit's assert.expect(number)
so much but Jasmine has no equivalent.
A proper test here should also probably spy on $onInit
(with calledThrough()
) to ensure it's not skipped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some issues to resolve indicated in comments. Otherwise, A good idea to abstract the $onInit
logic until support for AngularJS <1.5.10 is dropped.
@gkalpak @mgol @ThomasBurleson Updated the PR. |
}); | ||
|
||
it('disabled should assigns bindings after constructor', function() { | ||
configureCompiler(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's use:
var shouldPreAssign = false;
var isIntantiated = false;
configureCompiler(shouldPreAssign);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What advantage does this have? I think the spec name and function parameter already explain that this changes the preAssignBindings
behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to search for how it was disabled. the configureCompiler(false)
was not intuitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I understand. How is setPreAssignBindings
?
@devversion - please squash your commits. |
var hasPreAssignState = !!$compileProvider.preAssignBindingsEnabled; | ||
|
||
this.$get = function() { | ||
return hasPreAssignState ? $compileProvider.preAssignBindingsEnabled() : fallbackValue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not catch changes that will happend at runtime (which is theoretically possible, although highly improbable).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I intentionally did it that way. If users change it at runtime then I don't think this should be respected. Providers should be set at config phase.
function setPreAssignBindings(preAssignBindingsEnabled) { | ||
module(function($compileProvider) { | ||
$compileProvider.preAssignBindingsEnabled(preAssignBindingsEnabled); | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon 😱
|
||
var ctrl = invokeCtrl(); | ||
// Create the specified controller instance. | ||
var ctrl = self._createController(options, injectLocals, locals); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, injectLocals
and locals
are the same object. I assume this a bug, but not directly related to (or introduced by) this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what way are those similar? injectLocals
contains the $element
DI token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the way that angular.extend(locals, {$element: ...})
extends locals
with $element
and then returns locals
. So, injectLocals === locals
. I assume the intended behavior was injectLocals = angular.extend({$element: ...}, locals)
or injectLocals = angular.extend({}, locals, {$element: ...})
.
return data; | ||
} | ||
|
||
it('enabled should assigns bindings at instantiation', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assigns --> assign
expect(isInstantiated).toBe(true); | ||
}); | ||
|
||
it('disabled should assigns bindings after constructor', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assigns --> assign
@devversion - please squash your commits and rebase from master. |
295141e
to
d85d4d2
Compare
@ThomasBurleson Done. |
@devversion did you see my comment regarding the Karma update? This one: #10469 (comment). |
I just saw that I need to make one adjustment for the tests. Ignore the failing test for review. |
function PreAssignBindingsProvider($compileProvider) { | ||
// To avoid breaking changes in Material, AngularJS Material will only respect the | ||
// preAssignBindingsEnabled state in AngularJS 1.6.X and higher. | ||
var respectPreAssignState = angular.version.major === 1 && angular.version.minor > 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will break with AngularJS ~1.5.10
if the developer sets the preAssignBindingsEnabled
flag to false
.
What are the breaking changes mentioned in a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made some changes to it. See updated PR
var respectPreAssignState = angular.version.major === 1 && angular.version.minor > 5; | ||
|
||
this.$get = function() { | ||
return respectPreAssignState ? $compileProvider.preAssignBindingsEnabled() : true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will break in AngularJS 1.7+. We had a thread about it with @gkalpak suggesting an implementation that would work, what did happen with that? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation did not cover the changes we discussed in our meeting. Also we don't want to re-check the preAssignBindingsEnabled
state for each $mdCompiler
call (as it returned a getValue
function)
I changed it now to work as we discussed on our meeting
- 1.5: Bindings will be always pre-assigned as same as with Material before.
- 1.6: Angular Material will start respecting the
preAssignBindingsEnabled
state - 1.7: Compiler will always sets preAssignBindingsEnabled to false.
* The `$mdCompiler` now respects the `preAssignBindingsEnabled` state when using AngularJS 1.6 or higher. **BREAKING CHANGE** Developers that are upgrading from AngularJS 1.5 to AngularJS 1.6 may run into issues with their custom controllers. All custom controllers that are are being used inside of Material components, like in the `$mdDialog` or `$mdToast`, can be affected. > Limited to controllers that are used in combination with the `bindToController` and `locals` option. Angular Material starts respecting the [`preAssignBindingsEnabled`](angular/angular.js#15352) state when using AngularJS 1.6+ This will mean that bindings are no longer initialized at `constructor` time. ```js $mdDialog.show({ locals: { myVar: true }, controller: MyController, bindToController: true } function MyController() { // No locals from Angular Material are set yet. e.g myVar is undefined. } MyController.prototype.$onInit = function() { // Bindings are now set in the $onInit lifecycle hook. } ``` To provide consistency, Angular Material components with custom controllers now work with the `$onInit` lifecycle hook (**no** other lifecycle hooks) Fixes angular#10016
203c380
to
3b6f4a2
Compare
// To avoid that the preAssignBindings state causes issues when upgrading from AngularJS 1.5 to | ||
// AngularJS 1.6, AngularJS Material will only respect the preAssignBindingsEnabled state in 1.6 | ||
var respectPreAssignState = angular.version.major === 1 && angular.version.minor === 6; | ||
var fallbackValue = !!$compileProvider.preAssignBindingsEnabled; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @mgol has pointed out, this will break in the future (most probably 1.7+). The plan is to remove the preAssingBindingsEnabled
method and not support pre-assignement neither by default, nor as an opt-in (this is the PR btw: angular/angular.js#15782).
Base on what we have discussed in the last meeting, you need something like this:
var defaultPreAssignValue = angular.version.major === 1 && angular.version.minor < 6;
var respectPreAssignState = angular.version.major === 1 && angular.version.minor > 5 &&
$compileProvider.preAssignBindingsEnabled;
this.$get = function() {
return respectPreAssingState ? $compileProvider.preAssignBindingsEnabled() : defaultPreAssignState;
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, the current implementation will also break in 1.5.0-1.5.9 (where there is no $compileProvider.preAssignBindingsEnabled
method).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, the current implementation will also break in 1.5.0-1.5.9 (where there is no
$compileProvider.preAssignBindingsEnabled
method).
How so? fallbackValue
will then be false
but it won't be used anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fallbackValue
will be false
and it will be used. respectPreAssignState
would be false
, so the (incorrect) fallback value will be used.
(To be clear, by "current implementation" I mean the implementation currently used in this PR.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I thought that preAssignBindingsEnabled
has been added in 1.5.X and changed in 1.6 to false
by default and will be removed in 1.7.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkalpak Ah, you're right.
@devversion The flag has been added in 1.5.9 which was released after a long wait and even after 1.6.0 was released. It's highly likely most of 1.5.x users will not have this flag available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback value should be defined based on AngularJS version, not the presence of the $compileProvider.preAssignBindingsEnabled
flag.
Besides, as far as I understand, Material still supports AngularJS 1.3+, doesn't it?
function PreAssignBindingsProvider($compileProvider) { | ||
// To avoid that the preAssignBindings state causes issues when upgrading from AngularJS 1.5 to | ||
// AngularJS 1.6, AngularJS Material will only respect the preAssignBindingsEnabled state in 1.6 | ||
var respectPreAssignState = angular.version.major === 1 && angular.version.minor === 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About not respecting the flag in 1.5: it's about how MdCompilerService#_createController
behaves so it will not break 1.5, it will just still preassign bindings in 1.5.10 even if the developer sets preAssignBindingsEnabled
to false
, I see it now.
We could have respected the flag in 1.5.10 if your PR from a while ago accounting for this flag wasn't merged before this one as it wouldn't be breaking then - no one would be using 1.5.10 with Material & this flag set to false
as this configuration was broken.
I assume Material needs to ignore this flag because Material 1.1.3 works fine in 1.5.10 with this flag set to false
? (Does it?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, just in case we'd have to revert the removal and defer it to 1.8, it would be safer to check for angular.version.minor > 5
instead of angular.version.minor === 6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, regarding the argument for not respecting the flag in ~1.5.10
but respecting in ~1.6
- if someone was using Material with AngularJS 1.6 and it worked for them as the components they used worked fine, this change may break them.
Maybe it would be safer to release this as 1.2.0, not 1.1.5 and then not ignoring the flag if it exists?
What do you think? @devversion @gkalpak @ThomasBurleson
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if someone was using Material with AngularJS 1.6 and it worked for them as the components they used worked fine, this change may break them.
🤢 True.
It sounds like there is indeed no (reaconable) way to make this non-breaking (without making it opt-in - e.g. with an mdCompiler
flag) 😞
function PreAssignBindingsProvider($compileProvider) { | ||
// To avoid that the preAssignBindings state causes issues when upgrading from AngularJS 1.5 to | ||
// AngularJS 1.6, AngularJS Material will only respect the preAssignBindingsEnabled state in 1.6 | ||
var respectPreAssignState = angular.version.major === 1 && angular.version.minor === 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, just in case we'd have to revert the removal and defer it to 1.8, it would be safer to check for angular.version.minor > 5
instead of angular.version.minor === 6
@mmalerba can you presubmit this (but don't merge it if it passes)? |
@jelbourn latest is good, v1_1 has ~10 failures (this is with merging this PR into master at the commit v1_1 is currently synced to) |
Since there are edge cases that would break when this PR lands in its current state, I think we could do the following to not have to wait for Material 1.2 with landing it:
What do you think? |
@mmalerba - Can you elaborate. I admit that I do not understand your response. Is this PR invalid for a presubmit? If yes, then why ? |
@mgol - let's talk about your ideas offline in a call. Thx |
@ThomasBurleson there were 10 failures when I checked, which is a relatively small number and may include some that were just flakes. It can probably be merged with some shepherding from the caretaker |
1. The `$mdCompiler` is now able to respect the `preAssignBindingsEnabled` state when using AngularJS 1.5.10 or higher; to enable, invoke: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); 2. `$mdCompiler` now understands the `$onInit` lifecycle hooks in controllers. Note that no other AngularJS 1.5+ lifecycle hooks are supported currently. Invoking: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); will make bindings in Material custom components like `$mdDialog` or `$mdToast` only available in controller constructors if they are available in constructors of all other AngularJS controllers. By default this will happen in AngularJS 1.6 or newer. This can also be achieved with AngularJS >=1.5.10 <1.6.0 if: $compilerProvider.preAssignBindingsEnabled(false); is invoked. Example: ```js $mdDialog.show({ locals: { myVar: true }, controller: MyController, bindToController: true } function MyController() { // No locals from Angular Material are set yet. e.g myVar is undefined. } MyController.prototype.$onInit = function() { // Bindings are now set in the $onInit lifecycle hook. } ``` Huge thanks to Paul Gschwendtner (@devversion) for the initial draft version of this feature. Fixes angular#10016 Closes angular#10469
This PR evolved into PR #10726; PTAL. |
@mgol Thanks for continuing this. Closing my PR here. |
1. The `$mdCompiler` is now able to respect the `preAssignBindingsEnabled` state when using AngularJS 1.5.10 or higher; to enable, invoke: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); 2. `$mdCompiler` now understands the `$onInit` lifecycle hooks in controllers. Note that no other AngularJS 1.5+ lifecycle hooks are supported currently. Invoking: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); will make bindings in Material custom components like `$mdDialog` or `$mdToast` only available in controller constructors if they are available in constructors of all other AngularJS controllers. By default this will happen in AngularJS 1.6 or newer. This can also be achieved with AngularJS >=1.5.10 <1.6.0 if: $compilerProvider.preAssignBindingsEnabled(false); is invoked. Example: ```js $mdDialog.show({ locals: { myVar: true }, controller: MyController, bindToController: true } function MyController() { // No locals from Angular Material are set yet. e.g myVar is undefined. } MyController.prototype.$onInit = function() { // Bindings are now set in the $onInit lifecycle hook. } ``` Huge thanks to Paul Gschwendtner (@devversion) for the initial draft version of this feature. Fixes angular#10016 Ref angular#10469 Closes angular#10726
1. The `$mdCompiler` is now able to respect the `preAssignBindingsEnabled` state when using AngularJS 1.5.10 or higher; to enable, invoke: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); 2. `$mdCompiler` now understands the `$onInit` lifecycle hooks in controllers. Note that no other AngularJS 1.5+ lifecycle hooks are supported currently. Invoking: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); will make bindings in Material custom components like `$mdDialog` or `$mdToast` only available in controller constructors if they are available in constructors of all other AngularJS controllers. By default this will happen in AngularJS 1.6 or newer. This can also be achieved with AngularJS >=1.5.10 <1.6.0 if: $compilerProvider.preAssignBindingsEnabled(false); is invoked. Example: ```js $mdDialog.show({ locals: { myVar: true }, controller: MyController, bindToController: true } function MyController() { // No locals from Angular Material are set yet. e.g myVar is undefined. } MyController.prototype.$onInit = function() { // Bindings are now set in the $onInit lifecycle hook. } ``` Huge thanks to Paul Gschwendtner (@devversion) for the initial draft version of this feature. Fixes angular#10016 Ref angular#10469 Closes angular#10726
1. The `$mdCompiler` is now able to respect the `preAssignBindingsEnabled` state when using AngularJS 1.5.10 or higher; to enable, invoke: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); 2. `$mdCompiler` now understands the `$onInit` lifecycle hooks in controllers. Note that no other AngularJS 1.5+ lifecycle hooks are supported currently. Invoking: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); will make bindings in Material custom components like `$mdDialog` or `$mdToast` only available in controller constructors if they are available in constructors of all other AngularJS controllers. By default this will happen in AngularJS 1.6 or newer. This can also be achieved with AngularJS >=1.5.10 <1.6.0 if: $compilerProvider.preAssignBindingsEnabled(false); is invoked. Example: ```js $mdDialog.show({ locals: { myVar: true }, controller: MyController, bindToController: true } function MyController() { // No locals from Angular Material are set yet. e.g myVar is undefined. } MyController.prototype.$onInit = function() { // Bindings are now set in the $onInit lifecycle hook. } ``` Huge thanks to Paul Gschwendtner (@devversion) for the initial draft version of this feature. Fixes angular#10016 Ref angular#10469 Closes angular#10726
1. The `$mdCompiler` is now able to respect the `preAssignBindingsEnabled` state when using AngularJS 1.5.10 or higher; to enable, invoke: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); 2. `$mdCompiler` now understands the `$onInit` lifecycle hooks in controllers. Note that no other AngularJS 1.5+ lifecycle hooks are supported currently. Invoking: $mdCompilerProvider.respectPreAssignBindingsEnabled(true); will make bindings in Material custom components like `$mdDialog` or `$mdToast` only available in controller constructors if they are available in constructors of all other AngularJS controllers. By default this will happen in AngularJS 1.6 or newer. This can also be achieved with AngularJS >=1.5.10 <1.6.0 if: $compilerProvider.preAssignBindingsEnabled(false); is invoked. Example: ```js $mdDialog.show({ locals: { myVar: true }, controller: MyController, bindToController: true } function MyController() { // No locals from Angular Material are set yet. e.g myVar is undefined. } MyController.prototype.$onInit = function() { // Bindings are now set in the $onInit lifecycle hook. } ``` Huge thanks to Paul Gschwendtner (@devversion) for the initial draft version of this feature. Fixes #10016 Ref #10469 Closes #10726
$mdCompiler
now respects thepreAssignBindingsEnabled
state when using AngularJS 1.6 or higher.BREAKING CHANGE
Developers that are upgrading from AngularJS 1.5 to AngularJS 1.6 may run into issues with their custom controllers.
All custom controllers that are are being used inside of Material components, like in the
$mdDialog
or$mdToast
, can be affected.Angular Material starts respecting the
preAssignBindingsEnabled
state when using AngularJS 1.6+This will mean that bindings are no longer initialized at
constructor
time.To provide consistency, Angular Material components with custom controllers now work with the
$onInit
lifecycle hook (no other lifecycle hooks)Fixes #10016