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

Parent directive element doesn't wait for child animations to complete before being removed from DOM. #12003

Closed
Guardiannw opened this issue Jun 1, 2015 · 16 comments

Comments

@Guardiannw
Copy link

The issue occurs whenever I have at least two custom directives that are toggled by an ng-switch. I listen to the leave event on the directive so that I can transition out some of the child elements before it removes the parent from the DOM and switches to the other directive. NgAnimate is not waiting for the child animations to complete before it removes the parent from the DOM in order to display the other directive in the ng-switch.

This is important because I need to be able to transition out the directive's child elements before the directive is switched. For instance, I have a directive that has an ng-repeat in its template, and I want to stagger animate out all of the elements in that ng-repeat before the entire directive is removed from the DOM.

Angular Version: 1.4.0

The plunker demonstrating the lack of animation on the ng-repeat items is here: http://plnkr.co/edit/uV5PJcVCROPXgSvYUy10

I think that the problem is in the scope of the element. The things in the scope.$apply are not getting called. I have also tried this with the $destroy event on the element and it does the same thing. I am pretty positive this needs to be called in an $apply block or with a $digest following it in order to animate however.

That being said; if animations do perform, then they still need to hold off the parent element's removal and switching until they are completed.

Thanks guys,

@Narretz
Copy link
Contributor

Narretz commented Jun 3, 2015

Did this work before 1.4.0?

@Guardiannw
Copy link
Author

I never tested before 1.4 so I am not sure honestly

@matsko
Copy link
Contributor

matsko commented Jun 15, 2015

This is getting fixed in the next release for 1.4.2

@Guardiannw
Copy link
Author

Great! Thank you guys for your work

@matsko
Copy link
Contributor

matsko commented Jul 17, 2015

Sorry there has been a bit of a delay. It turns out that #12248 doesn't effect this issue. I will be working on this tomorrow.

@matsko
Copy link
Contributor

matsko commented Jul 17, 2015

Alright so looking at this properly now I want to verify what you're trying to do.

You want the outer contain element (in this case the ng-switch-when container) to wait for each of the inner repeat items to finish animating away before it is removed from the DOM yes? This doesn't exist in ngAnimate as of now, however, I think we could add a new property to ng-animate-children:

<div ng-swich-when="..." ng-animate-children="wait">...</div>

In 1.5 we aim to make this a better API, but that's still not concrete. For now this feature could work.

@matsko
Copy link
Contributor

matsko commented Jul 17, 2015

In future versions of Angular we may even have a CSS solution like this:

.switch-container.ng-leave {
   transition:0.5s linear all;
   --ng-animate-children: 'wait';
}
.switch-container.ng-leave.ng-leave-active { ... }

.ng-switch-container .repeat-items.ng-leave { ... }
.ng-switch-container .repeat-items.ng-leave.ng-leave-active { ... }

@Guardiannw
Copy link
Author

Yes that is exactly what I am trying to do. That would probably be ok for the time being. Ideally I think it would be great to have it there by default, but its ok if it isn't. It would be nice if the animations could hook into some "you are about ready to be destroyed" event, like the destroy event, and the parent would just have to wait. That way a directive could prepare for that scenario out of the box.

Just a thought,
but I am up for whatever way you guys think it'll work best. I don't know much of the implementation behind ng-Animate.

It does seem like since ngAnimateChildren by default animates the children in, that it should also animate them out before moving though.

What do you think?

@Guardiannw
Copy link
Author

I like the css solution much more than the wait parameter. I might be misunderstanding it, but it seems like the css solution would be much more dynamic.

@matsko
Copy link
Contributor

matsko commented Jul 21, 2015

Yes the CSS solution might just be apart of the plan for a future release, but it does require a build system. For now (1.4 and 1.5) we may need to stick with the wait param.

@Guardiannw
Copy link
Author

Ok, as long as we can get something that will do the job, changing it later is fine. Thanks @matsko,

@maaljam
Copy link

maaljam commented Feb 18, 2016

Is this feature still being added?

@vasilak
Copy link

vasilak commented Oct 28, 2016

Has this been implemented?

@Narretz Narretz modified the milestones: 1.6.x, 1.7.x Apr 12, 2018
@petebacondarwin petebacondarwin modified the milestones: 1.7.x, 1.7.x - won't fix May 16, 2018
@gkalpak
Copy link
Member

gkalpak commented Sep 26, 2018

AFAICT, this works in v1.7.4 (so it must have been fixed somewhere along the way).

@gkalpak gkalpak closed this as completed Sep 26, 2018
@Narretz
Copy link
Contributor

Narretz commented Oct 1, 2018

@gkalpak do you have an example for this? I wonder if this is the behavior we always want, or if it should have been optional.

@gkalpak
Copy link
Member

gkalpak commented Oct 1, 2018

Sorry, I probably spoke too soon. This doesn't really work exactly as OP requested it.
Playing around with an example, here is what I found out:

  1. ngAnimateChildren explicitly does not apply to leave animations. (This is intended behavior - not sure why 😕)
    From the docs:

    Note that even if ngAnimateChildren is set, no child animations will run when the parent element is removed from the DOM (leave animation).

  2. It is possible to have the child animations run. For example, you manually animating them (as in OP's example), with something like:

    $animate.on('leave', parentElem, (eventTarget, phase) => {
      if ((phase === 'start') && (eventTarget[0]=== parentElem[0])) {
        angular.forEach(parentElem.find('p'), p => $animate.leave(p));
      }
    });

    But the child animations will not be coordinated with the parent animation. I.e. the parent animation will not wait for child animations to complete before removing the parent element from the DOM. But it is possible to manually coordinate them (e.g. by specifying appropriate animation durations).

The example I used is here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants