angular / angular.js

AngularJS - HTML enhanced for web apps!
https://angularjs.org
MIT License
58.82k stars 27.5k forks source link

Animation not working with 1.4.x and ui-router: ng-hide-add and ng-hide-remove classes are not generated #12583

Closed ndaian closed 8 years ago

ndaian commented 9 years ago

My issue seems similar with https://github.com/angular/angular.js/issues/12267, I left a comment there but since that issue is closed, people might not read it. @matsko worked on that issue.

ng-hide-add and ng-hide-remove classes are not generated. I am not using Material.

Debugging ngAnimate I noticed that all animations are skipped because:

The element $rootElement points to is a comment and it is inserted by the ui-view directive which is present on the angular root element. "ui-view" is a directive belonging to https://github.com/angular-ui/ui-router.

When ngAnimate is initialized $rootElement receives the correct value but probably when ui-router inserts its comment right before the angular root element, $rootElement is not updated. So when the animation happens, $rootElement points to instead of

Because 'areAnimationsAllowed' function does not find the angular root element, it retursn false and all animations are skipped.

matsko commented 9 years ago

Is $rootElement always bound to a comment node when ui-router is used? Does this mean that all animations are broken when it is used? Will the comment node be placed as a sibling always to the element that is originally the rootElement?

matsko commented 9 years ago

Look at this example we have an app where the rootElement is on <html>:

https://angular-ui.github.io/ui-router/sample/#/

  1. Right click somewhere on the page and select inspect element.
  2. Goto console and run this angular.element($0).injector().get('$rootElement')

See how it's the HTML element?

How did your code end up being situated to where the view was created? Could you share your some code to show how your app is configured?

ndaian commented 9 years ago

I'll try to create a plunker and share it with you

ndaian commented 9 years ago

starting to work on plunker, but until I have it I can answer you question: in our code the ng-app directive is not on the html element but on the div element that has the ui-view directive.

ndaian commented 9 years ago

Here you have the plunker: http://plnkr.co/edit/uB94enS5J2AgI0fPiePM?p=preview

Put the following two breakpoints in angular-animate.js:

  • breakpoint B1: on line 1939: var activeAnimationsLookup = new $$HashMap();
  • breakpoint B2: on line 2392: var bodyElementDetected = false; (first line in function areAnimationsAllowed(element, parentElement, event))

Refresh the page

  • breakpoint B1 will be hit and in console you can see that $rootElement is "[<div ng-app=​"myapp" ng-controller=​"MainCtrl" ui-view>​…​</div>​]" = correct

Click on the "Test Animation" button

  • breakpoint B2 will be hit and in console you can see that $rootElement is "[<!-- uiView: -->]" = incorrect
  • F8 in Developer Tools to continue and you will see that the animation "sort of" happens
    • "sort of happens" - because the height doesn't start at zero
  • Disable breakpoints in Developer Tools and keep clicking on the "Test Animation" button. you will see that the animation will not happen anymore

This behavior is a bit different than what I see in our app. I our app the animation doesn't happen even when debugging. I think that here it works when debugging because of the plunker environment.

ndaian commented 9 years ago

Moving the ui-view directive from the ng-app element to its own element workarounds the ngAnimate issue. The comment is inserted now in front of the

element and
is not affected. The animation works now.

Using this

Instead of this

    <div ng-app="myApp" ui-view></div>
tonis2 commented 9 years ago

@ndaian wait how does the workaround work, i have exactly the same problem, but didnt get it to work.

mikehuebner commented 9 years ago

Same problem here on angular 1.4.4, any UI View animations just stopped working, pretty sure this is not an ngAnimate issue but a uiRouter issue. We can probably move this to their issues with the same plunk if @ndian agrees.

matsko commented 9 years ago

@ndaian would you mind testing against these files to see if things work: http://www.angular-dev.com/raf-fix/angular.js http://www.angular-dev.com/raf-fix/angular-animate.js

ageblade commented 9 years ago

I've just had a similar issue however the problem was with the following row: bodyElementDetected = isMatchingElement(parentElement, $$body); It is always false because the ui-view directive was assigned to the element and in the angular-animate code the $$body variable is initialized before ui-router populate the view. so it is never equal.

Just want to put it out here for anyone else who might have this problem.

matsko commented 9 years ago

Is this still an issue? In 1.4.7 there was a fix to the $$body service.

chance-an commented 9 years ago

I am using the latest AngularJS 1.5.0beta + UIRouter 1.4.7. The issue doesn't repro for me.

matsko commented 9 years ago

@ndaian what about you?

kevinsuh commented 9 years ago

i started having this issue as well. transitions between states are not adding classes from nganimate. any updates on progress?

Narretz commented 8 years ago

This bug still repros in this plnkr (https://github.com/angular/angular.js/issues/12583#issuecomment-131942396) with the current snapshot.

pocesar commented 8 years ago

having the same problem, but on ng-switch-when. using 1.4.8

Narretz commented 8 years ago

I had a look at this and it seems this happens because ngView / uiView are transclude: element directives, which means they replace the element on which they are with a comment node. But I'm not yet sure how the $rootElement value is actually replaced by the comment node.