Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parent ngIf not respecting child's animation to finish before parent is removed from DOM #23302

Open
JGhignatti opened this issue Apr 11, 2018 · 9 comments
Labels
area: animations freq2: medium P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent type: bug/fix
Milestone

Comments

@JGhignatti
Copy link

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Parent ngIf does not wait for child animation to finish before killing it, apparently only if child's animation does not use :leave.
Issue #15798 and #18305 are about the same thing. The user dharders said:

I should have specified that animateChild() is needed only if you have :leave animations in a child component and the parent is removed from the DOM.

but I would like to have the usage of that method for custom states.

Expected behavior

Parent ngIf waits for child's animation to finish before removing it form the DOM.

Minimal reproduction of the problem with instructions

I have this for my child component

animations: [
    trigger('slideUpDown', [
      state('hide', style({transform: 'translateY(100%)'})),
      state('show', style({transform: 'translateY(0)'})),
      transition('hide <=> show', animate('500ms ease-in-out'))
    ])
 ]

...

state: 'show'|'hide' = 'hide';
toggleView() {
    this.state = this.state === 'show' ? 'hide' : 'show';
}

and for my parent component

  • html:
<button (click)="toggle()">Click</button>
<div *ngIf="isVisible">
    <child #childComponent></child>
</div>
  • ts
@ViewChild('childComponent') childComponent: ChildComponent;
toggle() {
    this.childComponent.toggleState();
}

What is the motivation / use case for changing the behavior?

So child animations are respected when parent is about to be hidden.

Environment


Angular version: Angular-CLI 1.7.4 - "@angular/core": "^5.2.0"


Browser:
- [X] Chrome (desktop) version 65.0.3325.181
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: v8.11.1
- Platform:  Windows 10 64bit

Others:
@macjohnny
Copy link
Contributor

macjohnny commented Sep 27, 2018

Example

here is an example demonstrating the problem:

A child :leave or * => void transition is not animated if the parent element is removed from the dom via *ngIf.

Versions

the issue occurs with angular 6.1.9 and 7.0.0-beta.7

Workaround

Add a dummy-animation to the parent element with the *ngIf:

    trigger('blub', [
      transition('* => void', [
        query("@*", [animateChild()], {optional: true})
      ]),
    ])
<div *ngIf="showing" [@blub]>
  <div [@bla] style="background: blue; width: 200px; height: 50px"></div>
</div>

@matsko if I remember correctly there have been several issues with nested animations. However, here it is not a nested animation, but an animation triggered by a parent's *ngIf. Is this issue considered working as designed or a bug?

@Paduado
Copy link

Paduado commented Jan 21, 2019

Just bumped into this, is there any workaround?

josephperrott pushed a commit to angular/components that referenced this issue Mar 5, 2019
* fix(select): Fixes width-issue of select option panel in IE11

Fixes the select options panel width not matching the select width in IE11

Fixes #11609

* code cleanup

* fix leave-animation of select panel not working due to angular/angular#23302
josephperrott pushed a commit to angular/components that referenced this issue Mar 5, 2019
* fix(select): Fixes width-issue of select option panel in IE11

Fixes the select options panel width not matching the select width in IE11

Fixes #11609

* code cleanup

* fix leave-animation of select panel not working due to angular/angular#23302
@tsteuwer-accesso
Copy link

tsteuwer-accesso commented Apr 21, 2019

I am also having the same issue.

Angular CLI: 6.2.9
Node: 8.9.3
OS: linux x64
Angular: 6.1.10
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.8.9
@angular-devkit/build-angular     0.8.9
@angular-devkit/build-optimizer   0.8.9
@angular-devkit/build-webpack     0.8.9
@angular-devkit/core              0.8.9
@angular-devkit/schematics        0.8.9
@angular/cdk                      7.3.7
@angular/cli                      6.2.9
@angular/material                 7.3.7
@ngtools/webpack                  6.2.9
@schematics/angular               0.8.9
@schematics/update                0.8.9
rxjs                              6.2.2
typescript                        2.9.2
webpack                           4.16.4

@Danebrouwer97
Copy link

Any news on this?

@oliveshell
Copy link

I met the issue too,any solution?

@Danebrouwer97
Copy link

Danebrouwer97 commented Apr 1, 2020

@jasonaden @matsko Is it possible to get someone assigned to this so we could liaise with them? I'm not sure how to take this further.

@JGhignatti
Copy link
Author

There's a work around that can make it work. It consists of creating a "dumb" animation to place on the tag with *ngIf that lets your child node finishes its animation before disappearing.

export function dumbParent(): AnimationTriggerMetadata {
  return trigger('dumbParent', [
    transition('* => void', [
      query('@*', [animateChild()], {optional: true})
    ]),
  ]);
}

export function dropdownFadeOut(): AnimationTriggerMetadata {
  return trigger('dropdownFadeOut', [
    transition(':leave', [
      group([
        query('i',
          animate('300ms ease-out', style({transform: 'rotateZ(0deg)'}))
        ),
        animate('200ms 200ms', style({opacity: 0}))
      ])
    ]),
  ]);
}

and then

<div *ngIf="<condition>" [@dumbParent]>
  <div [@dropdownFadeOut]>...</div>
</div>

@clement94
Copy link

I encountered the same problem: https://stackoverflow.com/questions/61455302/leave-transition-does-not-work-when-ngif-is-on-parent-component
Unfortunately the workaround cannot be applied in my situation (child component where the animation is declared is codded on a library and I can't change all projects which are using this library). Thanks for your help

@jelbourn jelbourn added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed severity3: broken labels Oct 1, 2020
@DmitryEfimenko
Copy link

I encountered a similar issue without the ngIf being a factor. Here's an approximate pseudo code of my situation:

@Component({
  template: `
  <parent [@animateBorder]="isOpen">
    <child [@animateWidth]="isOpen"></child>
  </parent>
  `
  animations: [animateBorder, animateWidth]
})
class MyComponent {
  @Input() isOpen = true;
}

The animateWidth animation would not work as expected if animateBorder animation is placed on the parent.
The workaround by @JGhignatti fixed the issue for me:

trigger('animateBorder', [
    state('true', style({ border: 0 })),
    state('false', style({ border: '1px solid red' })),
    transition('true => false', [
      group([
        // this is needed for animations on child elements to keep working
        query('@*', [animateChild()], { optional: true }),
        animate('300ms ease-in', style({ border: '1px solid red' })),
      ]),
    ]),
    transition('false => true', [
      group([
        // this is needed for animations on child elements to keep working
        query('@*', [animateChild()], { optional: true }),
        animate('300ms ease-in', style({ border: 0 })),
      ]),
    ]),
  ]);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: animations freq2: medium P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent type: bug/fix
Projects
None yet
Development

No branches or pull requests