-
Notifications
You must be signed in to change notification settings - Fork 27.4k
refactor(input): remove $$parserName from email, url #14292
Conversation
Since email and url don't use $parsers, we do not need to set the parserName. This also reduces the number of times the valid / invalid classes are set within for the input or possible parent forms. This was discovered when fixing angular#14249. The additional class settings triggered a cancellation of the structural animation. A general fix for this behavior has landed as <insert commit here>
For one, I believe this is a (tiny) Breaking Change, because previously we had If the problem is caused by trying to add/remove the same class multiple times (or trying to add and remove the same class) - once because of a validator and once because of the parser (which happens to have the same name as the validator), then we are not really solving it. That same problem could happen, if the user chose to add a validator with the same name as I believe we could instead fix this inside if (!parserValid) {
forEach(ctrl.$validators, function(v, name) {
- setValidity(name, null);
+ if (name !== errorKey) setValidity(name, null);
});
forEach(ctrl.$asyncValidators, function(v, name) {
- setValidity(name, null);
+ if (name !== errorKey) setValidity(name, null);
});
}
// Set the parse error last, to prevent unsetting it, should a $validators key == parserName
setValidity(errorKey, parserValid); or better yet (to avoid the same error when if (!parserValid) {
+ Object.keys(ctrl.$validators || {}).
+ concat(Object.keys(ctrl.$asyncValidators || {})).
+ filter(function (key, idx, arr) { return (key !== errorKey) && (arr.indexOf(key) === idx); }).
+ forEach(function (key) { setValidity(key, null); });
- forEach(ctrl.$validators, function(v, name) {
- setValidity(name, null);
- });
- forEach(ctrl.$asyncValidators, function(v, name) {
- setValidity(name, null);
- });
}
// Set the parse error last, to prevent unsetting it, should a $validators key == parserName
setValidity(errorKey, parserValid); |
With this change, we have now an additional I know that this doesn't fix all the cases where this can happen, I was just confused why url and email define the $$parserName at all. Maybe because they had a badInputChecker at some time (which uses a parser). |
It's not only for our parsers; the same name will be set if the user adds their parsers to the input. Just to be clear, there are two things I am saying here:
WDYT @Narretz ? |
I forgot about other parsers, yes that's right. I'm in favor of fixing this "right" with a BC in 1.6. I'd actually like to get rid of $$parserName and the while undefined === invalid thing, too, but I don't know if it's too big of a change at this point in 1.x |
This commit changes how input elements use the private $$parserName property on the ngModelController to name parse errors. Until now, the input types (number, date etc.) would set $$parserName when the inputs were initialized, which meant that any other parsers on the ngModelController would also be named after that type. The effect of that was that the `$error` property and the `ng-invalid-...` class would always be that of the built-in parser, even if the custom parser had nothing to do with it. The new behavior is that the $$parserName is only set if the actual parser is invalid, i.e. returns `undefined`. Also, $$parserName has been removed from input[email] and input[url], as these types do not have a built-in parser anymore. BREAKING CHANGE: Custom parsers that fail to parse on input types email, url, date, month, time, datetime-local, week, do no longer set $error[inputType], and no longer set the class `ng-invalid-[inputType]`. Instead, they set $error.parse and `ng-invalid-parse`. Closes angular#14292 Closes angular#10076
This commit changes how input elements use the private $$parserName property on the ngModelController to name parse errors. Until now, the input types (number, date etc.) would set $$parserName when the inputs were initialized, which meant that any other parsers on the ngModelController would also be named after that type. The effect of that was that the `$error` property and the `ng-invalid-...` class would always be that of the built-in parser, even if the custom parser had nothing to do with it. The new behavior is that the $$parserName is only set if the built-in parser is invalid i.e. returns `undefined`. Also, $$parserName has been removed from input[email] and input[url], as these types do not have a built-in parser anymore. BREAKING CHANGE: *Custom* parsers that fail to parse on input types "email", "url", "number", "date", "month", "time", "datetime-local", "week", do no longer set `ngModelController.$error[inputType]`, and the `ng-invalid-[inputType]` class. Also, custom parsers on input type "range" do no longer set `ngModelController.$error.number` and the `ng-invalid-number` class. Instead, any custom parsers on these inputs set `ngModelController.$error.parse` and `ng-invalid-parse`. Closes angular#14292 Closes angular#10076
This commit changes how input elements use the private $$parserName property on the ngModelController to name parse errors. Until now, the input types (number, date etc.) would set $$parserName when the inputs were initialized, which meant that any other parsers on the ngModelController would also be named after that type. The effect of that was that the `$error` property and the `ng-invalid-...` class would always be that of the built-in parser, even if the custom parser had nothing to do with it. The new behavior is that the $$parserName is only set if the built-in parser is invalid i.e. returns `undefined`. Also, $$parserName has been removed from input[email] and input[url], as these types do not have a built-in parser anymore. Closes #14292 Closes #10076 Closes #16347 BREAKING CHANGE: *Custom* parsers that fail to parse on input types "email", "url", "number", "date", "month", "time", "datetime-local", "week", do no longer set `ngModelController.$error[inputType]`, and the `ng-invalid-[inputType]` class. Also, custom parsers on input type "range" do no longer set `ngModelController.$error.number` and the `ng-invalid-number` class. Instead, any custom parsers on these inputs set `ngModelController.$error.parse` and `ng-invalid-parse`. This change was made to make distinguishing errors from built-in parsers and custom parsers easier.
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
What is the current behavior? (You can also link to an open issue here)
What is the new behavior (if this is a feature change)?
Does this PR introduce a breaking change?
Please check if the PR fulfills these requirements
Other information:
Since email and url don't use $parsers, we do not need to set the parserName.
This also reduces the number of times the valid / invalid classes are
set within for the input or possible parent forms.
This was discovered when fixing #14249. The additional class settings triggered
a cancellation of the structural animation. A general fix for this behavior has
landed as