Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

ngForm stays $dirty after control.$setPristine() #13715

Closed
@jar240

Description

@jar240

Hi there. Frustrating problem. in an ngForm, if in my controller I set one of the form's controls to $dirty (via control.$setDirty()), then in the controller set the same control to $pristine, the form remains $dirty.

  1. on state load, form is $pristine
  2. via another event, call controller function that does control.$setDirty() - form is now $dirty
  3. via another event, call controller function that does control.$setPristine() - form is still $dirty

I'm pretty sure this shouldn't happen, and is getting kludgy to fix. I'm using Angular 1.4.8.

Plunkr:
https://plnkr.co/edit/6noEtj6vbMkqxiKK6Yp7?p=preview

Thanks

Activity

gkalpak

gkalpak commented on Jan 9, 2016

@gkalpak
Member

I'm pretty sure this is how it is supposed to work. ngForm does not keep track of which controls are pristine/dirty. Setting a control to $dirty will propagation the "dirty-ness" to the parent form controllers, but setting all controls to $pristine will not set the parent form(s) to $pristine as well.

It's not an unreasonable feature to request, but it would add a tiny bit of overhead (which won't be necessary for most apps).

If you need such functionality, you can always implement a work-around.
In any case, this will be much easier if/when we expose the controls array.

@Narretz, do you think it is reasonable to check if all controls are $pristine (whenever a control is set to $pristine) and set the parent form to $pristine too (if all controls are $pristine) ?

Narretz

Narretz commented on Jan 11, 2016

@Narretz
Contributor

User expectation is probably that the form is set to $pristine, and I can see how that makes sense. We have the same problem with $setValidity, too, afaik.
I'm not to keen about implementing this logic. A parent form form would potentially need to loop through hundreds of children to determine its pristine-ness.
Either we make this check available behind a flag, or we expose the child forms / child controls on the form element, so that developers can loop over them themselves.

added this to the Ice Box milestone on Jan 11, 2016
added a commit that references this issue on Jan 15, 2016
61ac267
linoleum-js

linoleum-js commented on Jan 15, 2016

@linoleum-js

I wrote some brute force solution, but.. what if we will keep track of number of nested pristine controls/forms? 0 by default, it will be increased in $setPristin and decreased in $setDirty. By comparing it each time with controls.length we will get $pristine. I'm not sure what should happen when we add/remove controls, but i guess it can be solved too.

gkalpak

gkalpak commented on Jan 15, 2016

@gkalpak
Member

Having an internal counter also seems like a viable solution. I can't think of a corner case that could not be handled with such an implementation (if implemented properly).

jar240

jar240 commented on Jan 15, 2016

@jar240
Author

Hi, thanks for considering this.

I understand that revalidating the entire form to check for $pristine is a an inexpensive operation relative to setting the form to $dirty when a single control is set dirty. I like the idea of counters for the $touched, $untouched, $pristine and $dirty status of each field, since we only care whether or not the counter is 0 each.

added 2 commits that reference this issue on Jan 19, 2016
da2bfb6
17c4335

4 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      ngForm stays $dirty after control.$setPristine() · Issue #13715 · angular/angular.js