17

there is a ng-if animation example in this doc:https://docs.angularjs.org/api/ng/directive/ngIf if you clicking the checkbox quickly and repeatedly,you will find more than one element will be displayed,I don't know how to avoid it.

fenyiwudian
  • 470
  • 3
  • 12

1 Answers1

12

This happens because ngIf behaves different to ngShow for example. ngShow simply adds a display: none style to the element that must be hidden, while ngIf does the following:

The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.

So if the animation takes a bit long, there will be more than one element in the DOM.

In Olivvv's example, if you just change the delay of .animate-if.ng-enter, .animate-if.ng-leave to 0.001s you will se that you cannot get more than one element.

Here for you to see it is a forked version of the official AngularJS documentation. http://plnkr.co/edit/ok7nwOIRpR1TYYRkBRXj?p=preview

I have only modified its delay from 0.5s to 0.001s

Ignacio Villaverde
  • 1,264
  • 1
  • 11
  • 15
  • Thanks for the explanation. So the cloning is faster than the removing, and they don't block each-other ? so if want to keep the animation "long", what is the solution ? add a debouncer to prevent clicks to trigger toggle action whilst the animation is still running ? (btw, shouldn't angular as a framework take care of this? imo we should not get race conditions just by using the most standard condition) – Olivvv Jan 28 '16 at 09:51
  • First of all remember AngularJS is being used by millions of people, so I believe that for the dilemma of keeping it standard but forcing you to use it that way, or giving you freedom to use it as you want, they kept with the second. – Ignacio Villaverde Jan 28 '16 at 15:10
  • So another thing you should consider, is using ngShow, which is considered a better solution when the state is being modified often. You don't need to remove it from de DOM and recreate it each time. You could do what you mentioned with a debouncer to prevent clicks but, is that a good UX solution? Or it is just an almost-dirty workaround? – Ignacio Villaverde Jan 28 '16 at 15:11
  • I will suggest to use ngShow if the state can be modified by the user, because the user could simply keep changing the state quite often. I belive ngIf was not thought for things like this. – Ignacio Villaverde Jan 28 '16 at 15:11
  • @Olivvv could you assign the bounty? – Ignacio Villaverde Feb 04 '16 at 05:32
  • no sorry it seems that I cant, I am not the author of the original question. – Olivvv Feb 04 '16 at 10:48
  • Thank you very much, glad to help you! – Ignacio Villaverde Feb 04 '16 at 16:00