-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(ngModelOptions): work correctly when on the template of replace
directives
#15493
Conversation
… directives Previously, in order for `ngModel` and `ngModelOptions` to work correctly together, the latter's pre-linking function should be run before the former's pre-linking function. This was typically what happened, except when `ngModel` was used on an element which also had a `replace` directive, whose template included `ngModelOptions`. In that case, the order was reversed. This commit fixes it by moving the initialization logic of `ngModelOptions` from its pre-linking function to its controller's `$onInit()` lifecycle hook. Fixes angular#15492
On the surface I like the look of this! I need to spend some time tomorrow checking 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.
One minor naming suggestion but LGTM.
Good fix @gkalpak
optionsCtrl.$options = parentOptions.createChild(scope.$eval(attrs.ngModelOptions)); | ||
} | ||
} | ||
require: {parentOptionsCtrl: '?^^ngModelOptions'}, |
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 think the reason why I moved it to the pre-link function is because this feature of requiring directly onto the controller was either not available or very new.
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.
IIRC this is the first occurrence of this feature in Angular's codebase 🏋️
} | ||
NgModelOptionsController.prototype = { | ||
$onInit: function() { | ||
var parentCtrl = this.parentOptionsCtrl; |
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.
given that we can name the binding anything we like why not just call it parentCtrl
and then there would be very little motivation for this line any more.
…eplace` directives
… directives Previously, in order for `ngModel` and `ngModelOptions` to work correctly together, the latter's pre-linking function should be run before the former's pre-linking function. This was typically what happened, except when `ngModel` was used on an element which also had a `replace` directive, whose template included `ngModelOptions`. In that case, the order was reversed. This commit fixes it by moving the initialization logic of `ngModelOptions` from its pre-linking function to its controller's `$onInit()` lifecycle hook. Fixes #15492 Closes #15493
… directives Previously, in order for `ngModel` and `ngModelOptions` to work correctly together, the latter's pre-linking function should be run before the former's pre-linking function. This was typically what happened, except when `ngModel` was used on an element which also had a `replace` directive, whose template included `ngModelOptions`. In that case, the order was reversed. This commit fixes it by moving the initialization logic of `ngModelOptions` from its pre-linking function to its controller's `$onInit()` lifecycle hook. Fixes angular#15492 Closes angular#15493
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix.
What is the current behavior? (You can also link to an open issue here)
In order for
ngModel
andngModelOptions
to work correctly together, the latter's pre-linking function should be run before the former's pre-linking function. This is typically what happens, except whenngModel
is used on an element which also has areplace
directive, whose template includesngModelOptions
. In that case, the order is reversed.See #15492 for more details.
What is the new behavior (if this is a feature change)?
The initialization logic of
ngModelOptions
is moved from its pre-linking function to its controller's$onInit()
lifecycle hook. This way, it is always guaranteed to be run beforengModel
's pre-linking function, even in thereplace
scenario mentioned above.Does this PR introduce a breaking change?
Maybe.
There is no breaking change wrt 1.5.x (where the initialization of
ngModelOptions
used to take place in the controller itself), but wrt to 1.6.0 the following usecase will no longer be possible:A sibling directive to
ngModelOptions
, let's call itfoo
could be modifying the model options definition (e.g.ng-model-options="modelOptionsDefinition"
) in its$onInit()
lifecycle hook. If thefoo
directive had a lower priority thatngModelOptions
, then it will no longer work after this PR, since its$onInit()
method will be called afterngModelOptions
is initialized.(This can be worked around by changing the priority of
foo
to be higher thanngModelOptions
or by overwritingngModelOptions#$options
fromfoo#$onInit()
.Please check if the PR fulfills these requirements
Docs have been added / updated (for bug fixes / features)Other information:
Fixes #15492.