-
Notifications
You must be signed in to change notification settings - Fork 27.4k
input[type=date] borks model on binding if ngRequired is falsey #9996
Comments
I think the reason for returning empty string is to have equality between $viewValue and actual DOM value. IIRC browsers that support date won't set invalid date strings as values - though that could be the case for throwing actually. |
Set $viewValue to '' to match DOM, why not, but then why changing the model? |
"changing the model" is the bug ----- Ursprüngliche Nachricht ----- Set $viewValue to '' to match DOM, why not, but then why changing the model? |
Ok. |
Mmmm... Ok, but the formatter in the stringBasedInputType function returns the original value if the value evaluates to isEmpty (which is used by input[type] text, email, and url).
As does the one in the numberInputType function (used by input[type] number).
The only other built-in formatters that I found in the angular code were for checkbox and ngList which are both kind of special cases anyway. Is matching the DOM value something that is needed? If so, it would seem to me that these other formatters for those input types mentioned should be modified to return an empty string as well. If not, then returning the original value would seem to be an adequate fix. Thoughts? |
@EverPresent this sounds like a good idea, actually. What makes me wonder though: when the model gets formatted to |
I'm playing around with this and thought I would post a little more info for your consumption. When the formatter receives The crux of this bug, I think, is occurring when the parser converts the empty string into a Both |
When the view has been changed by the model (=formatters have run), the parsers should not be called at all, the model must stay what it was before calling the formatters and there is no point in calling the parsers. Attention: this is the description of how it should behave according to me, not at all an analysis of the current behavior of AngularJS. Fred |
I'm not entirely sure what the current behavior of angular is in regards to your comments. But I think you would get better feedback from the entire body of core developers if you posted those ideas on the dev mailing list or opened a separate issue to discuss proposed changes. |
Previously, $validate would execute the parsers to obtain a modelValue for validation. This was necessary, because a validator that is called outside of model / view update (e.g. from an observer) otherwise might only an undefined modelValue, because a previous view update has found a validation $error and set the model to undefined (as is tradition in angular) This is problematic as validators that are run immediately after the ngModelController initializes would parse the modelValue and replace the model, even though there had been no user input. The solution is to go back to an older design: the ngModelController will now internally record the $$rawModelValue. This means a model or view update will store the set / parsed modelValue regardless of validity, that is, it will never set it to undefined because of validation errors. When $validate is called, the $$rawModelValue will passed to the validators. If the validity has changed, the usual behavior is kept: if it became invalid, set the model to undefined, if valid, restore the last available modelValue - the $$rawModelValue. Additionally, $validate will only update the model when the validity changed. This is to prevent setting initially invalid models other than undefined to undefined (see angular#9063) Fixes: angular#9063 Fixes: angular#9959 Fixes: angular#9996 Fixes: angular#10025 Closes: angular#9890 Closes: angular#9913 Closes: angular#9997
Previously, $validate would execute the parsers to obtain a modelValue for validation. This was necessary, because a validator that is called outside of model / view update (e.g. from an observer) otherwise might only an undefined modelValue, because a previous view update has found a validation $error and set the model to undefined (as is tradition in angular) This is problematic as validators that are run immediately after the ngModelController initializes would parse the modelValue and replace the model, even though there had been no user input. The solution is to go back to an older design: the ngModelController will now internally record the $$rawModelValue. This means a model or view update will store the set / parsed modelValue regardless of validity, that is, it will never set it to undefined because of validation errors. When $validate is called, the $$rawModelValue will passed to the validators. If the validity has changed, the usual behavior is kept: if it became invalid, set the model to undefined, if valid, restore the last available modelValue - the $$rawModelValue. Additionally, $validate will only update the model when the validity changed. This is to prevent setting initially invalid models other than undefined to undefined (see angular#9063) Fixes: angular#9063 Fixes: angular#9959 Fixes: angular#9996 Fixes: angular#10025 Closes: angular#9890 Closes: angular#9913 Closes: angular#9997
Previously, $validate would execute the parsers to obtain a modelValue for validation. This was necessary, because a validator that is called outside of model / view update (e.g. from an observer) otherwise might only an undefined modelValue, because a previous view update has found a validation $error and set the model to undefined (as is tradition in angular) This is problematic as validators that are run immediately after the ngModelController initializes would parse the modelValue and replace the model, even though there had been no user input. The solution is to go back to an older design: the ngModelController will now internally record the $$rawModelValue. This means a model or view update will store the set / parsed modelValue regardless of validity, that is, it will never set it to undefined because of validation errors. When $validate is called, the $$rawModelValue will passed to the validators. If the validity has changed, the usual behavior is kept: if it became invalid, set the model to undefined, if valid, restore the last available modelValue - the $$rawModelValue. Additionally, $validate will only update the model when the validity changed. This is to prevent setting initially invalid models other than undefined to undefined (see angular#9063) Fixes: angular#9063 Fixes: angular#9959 Fixes: angular#9996 Fixes: angular#10025 Closes: angular#9890 Closes: angular#9913 Closes: angular#9997
@frfancha Bug:
Expected:
|
Previously, $validate would execute the parsers to obtain a modelValue for validation. This was necessary, because a validator that is called outside of model / view update (e.g. from an observer) otherwise might only an undefined modelValue, because a previous view update has found a validation $error and set the model to undefined (as is tradition in angular) This is problematic as validators that are run immediately after the ngModelController initializes would parse the modelValue and replace the model, even though there had been no user input. The solution is to go back to an older design: the ngModelController will now internally record the $$rawModelValue. This means a model or view update will store the set / parsed modelValue regardless of validity, that is, it will never set it to undefined because of validation errors. When $validate is called, the $$rawModelValue will passed to the validators. If the validity has changed, the usual behavior is kept: if it became invalid, set the model to undefined, if valid, restore the last available modelValue - the $$rawModelValue. Additionally, $validate will only update the model when the validity changed. This is to prevent setting initially invalid models other than undefined to undefined (see angular#9063) Fixes: angular#9063 Fixes: angular#9959 Fixes: angular#9996 Fixes: angular#10025 Closes: angular#9890 Closes: angular#9913 Closes: angular#9997
Previously, $validate would execute the parsers to obtain a modelValue for validation. This was necessary, because a validator that is called outside of model / view update (e.g. from an observer) otherwise might only an undefined modelValue, because a previous view update has found a validation $error and set the model to undefined (as is tradition in angular) This is problematic as validators that are run immediately after the ngModelController initializes would parse the modelValue and replace the model, even though there had been no user input. The solution is to go back to an older design: the ngModelController will now internally record the $$rawModelValue. This means a model or view update will store the set / parsed modelValue regardless of validity, that is, it will never set it to undefined because of validation errors. When $validate is called, the $$rawModelValue will passed to the validators. If the validity has changed, the usual behavior is kept: if it became invalid, set the model to undefined, if valid, restore the last available modelValue - the $$rawModelValue. Additionally, $validate will only update the model when the validity changed. This is to prevent setting initially invalid models other than undefined to undefined (see angular#9063) Fixes: angular#9063 Fixes: angular#9959 Fixes: angular#9996 Fixes: angular#10025 Closes: angular#9890 Closes: angular#9913 Closes: angular#9997 Closes: angular#10048
Previously, $validate would execute the parsers to obtain a modelValue for validation. This was necessary, because a validator that is called outside of model / view update (e.g. from an observer) otherwise might only an undefined modelValue, because a previous view update has found a validation $error and set the model to undefined (as is tradition in angular) This is problematic as validators that are run immediately after the ngModelController initializes would parse the modelValue and replace the model, even though there had been no user input. The solution is to go back to an older design: the ngModelController will now internally record the $$rawModelValue. This means a model or view update will store the set / parsed modelValue regardless of validity, that is, it will never set it to undefined because of validation errors. When $validate is called, the $$rawModelValue will passed to the validators. If the validity has changed, the usual behavior is kept: if it became invalid, set the model to undefined, if valid, restore the last available modelValue - the $$rawModelValue. Additionally, $validate will only update the model when the validity changed. This is to prevent setting initially invalid models other than undefined to undefined (see angular#9063) Fixes: angular#9063 Fixes: angular#9959 Fixes: angular#9996 Fixes: angular#10025 Closes: angular#9890 Closes: angular#9913 Closes: angular#9997 Closes: angular#10048
This is fixed in 1.3.4. |
@Narretz |
This bug still seems to be happening in 1.3.8 & 1.3.10 |
@weagle08 I tried the plunker and it shows the same result for the latest snapshot and the fixed version that was included. If you are referring to a different error, please open a new issue. Thanks! |
So this wasn't a problem in the previous version of angular that I was running (1.2.*?) but as soon as I upgraded to 1.3.1 all of my required date input types would set my model value to null upon binding (which would fire my $watches prematurely and cause havok).
It seems there have been a lot of input controller related issues arise in 1.3 but looking through the open issues I don't think this one has any related.
Check out this plunk to verify the issue:
http://plnkr.co/edit/dgsiLXD4OTDt19FF6pmi?p=info
I tracked down the problem to the default formatter that is attached to the input in input.js:createDateInputType. It is returning an empty string if the value evaluates to isEmpty. Looking at other formatters the rule of thumb seems to be to return the original value that evaluated to falsey (not change it to empty string). I made this one line change and if you click the "see fixed version" at the bottom of the plunk you will see the exact same page using my fixed version of the angular.js file.
The text was updated successfully, but these errors were encountered: