-
Notifications
You must be signed in to change notification settings - Fork 27.4k
refactor($compile): remove preAssignBindingsEnabled leftovers #16580
Conversation
src/auto/injector.js
Outdated
return fn.apply(self, args); | ||
} else { | ||
if (isClass(fn)) { | ||
// This code path was used by $controller previously and is not really needed any more. |
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.
Can we remove these hacks? Or would it be considered a breaking change in the public API? This behavior of invoke
isn't documented.
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.
Since fn
is documented to be a function (not a class) and it doesn't make sense to call invoke on a class, it is fine to remove this imo.
6b9a0fc
to
219c0f0
Compare
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.
Generally LGTM.
I was surprized that no tests needed to be changed/removed.
src/auto/injector.js
Outdated
return fn.apply(self, args); | ||
} else { | ||
if (isClass(fn)) { | ||
// This code path was used by $controller previously and is not really needed any more. |
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.
Since fn
is documented to be a function (not a class) and it doesn't make sense to call invoke on a class, it is fine to remove this imo.
src/ng/controller.js
Outdated
@@ -81,16 +81,12 @@ function $ControllerProvider() { | |||
* It's just a simple call to {@link auto.$injector $injector}, but extracted into | |||
* a service, so that one can override this service with [BC version](https://gist.github.com/1649788). | |||
*/ | |||
return function $controller(expression, locals, later, ident) { | |||
return function $controller(expression, locals, _ignored, ident) { |
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.
Theoretically, we can do whatever we want with "private", undocumented params 😁
src/ng/controller.js
Outdated
// If true, $controller will allocate the object with the correct | ||
// prototype chain, but will not invoke the controller until a returned | ||
// callback is invoked. | ||
// param `_ignored` --- not used, kept for compatibility with the $controller decorator in ngMock |
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.
Why keep the unused param and not change the decorated ngMock
$controller
?
src/ng/compile.js
Outdated
var require = controllerDirective.require; | ||
if (controllerDirective.bindToController && !isArray(require) && isObject(require)) { | ||
extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers)); | ||
var instance = $controller(controllerConstructor, locals, false, directive.controllerAs); |
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.
One difference with the previous implementation is that all controller instances where available on the element before instantiating a controller. (Now it depends on the relative order of controllers.)
But I think this is fine since it is not recommended to access controllers directly off of $element
, but require them and access them in ngOnInit()
.
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.
'Instances available before instantiation` is exactly what we're getting rid of.
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 really 😁
First of all, this is a refactoring commit, so we shouldn't be getting rid of anything 😛
The associated, feature-removing PR got rid of bindings (and instances?) being assigned to the controller instance before instantiation. But if someone tried to grab the instances with $element.controller('xyz')
, they would be there (possibly uninstantiated, but that doesn't matter).
So, one could argue that this commit introduces a breaking change. But like I said, "I think this is fine since it is not recommended to access controllers directly off of $element
, but one should require them and access them in ngOnInit()
". 😃
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.
they would be there (possibly uninstantiated, but that doesn't matter)
And only if the class isn't an ES6 class.
@gkalpak I've addressed all the comments. Please have a look. |
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.
LGTM as soon as Travis is happy 👍
162ba2c
to
a88048f
Compare
Travis's unhappiness seems to be unrelated to my changes. |
I think the minor concerns in this comment chain: #16580 (comment) should be included in some form in the commit message. In the off chance that this affects someone, it makes it easier to recap what happened. |
@Narretz Ok, added it.
If those people access other controllers via |
Now that we don't need to support `preAssignBindingsEnabled` (removed in angular#15782), complexity introduced in `$controller` by angular#7645 can be removed. One difference with the previous implementation is that all non-ES2015-class controller instances were available on the element before calling their constructors. Now it depends on the relative order of controllers. Controller constructors shouldn't be used to access other controllers (e.g. via `$element.controller(directiveName)`). The recommended way is to use the `require` property of the directive definition object and the life cycle hooks `$onChanges` or `$onInit`. See https://docs.angularjs.org/api/ng/service/$compile#-require- https://docs.angularjs.org/api/ng/service/$compile#life-cycle-hooks
Well, |
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.
Approve, but we need to be prepared that some people have been requiring the controllers via element in the constructor. ;)
Now that we don't need to support `preAssignBindingsEnabled` (removed in #15782), complexity introduced in `$controller` by #7645 can be removed. One difference with the previous implementation is that all non-ES2015-class controller instances were available on the element before calling their constructors. Now it depends on the relative order of controllers. Controller constructors shouldn't be used to access other controllers (e.g. via `$element.controller(directiveName)`). The recommended way is to use the `require` property of the directive definition object and the life cycle hooks `$onChanges` or `$onInit`. See https://docs.angularjs.org/api/ng/service/$compile#-require- https://docs.angularjs.org/api/ng/service/$compile#life-cycle-hooks Closes #16580
Now that we don't need to support
preAssignBindingsEnabled
(removed in #15782), complexity introduced in$controller
by #7645 can be removed.