components icon indicating copy to clipboard operation
components copied to clipboard

bug(table): ngOnDestroy clears view before route animations finish

Open brandom opened this issue 7 years ago • 27 comments

Reproduction

https://angular-components-8057.stackblitz.io (updated to 9.2.4)

Steps to reproduce:

  1. Navigate to "Page" and the table view is destroyed immediately.

Expected Behavior

Table should remain in DOM until animations finish.

Actual Behavior

Table is removed from DOM as soon as routing begins.

Environment

  • Angular: 9.1.9
  • CDK/Material: 9.2.4
  • Browser(s): Google Chrome
  • Operating System (e.g. Windows, macOS, Ubuntu): macOS

brandom avatar Oct 26 '17 19:10 brandom

@andrewseguin I looked at the reproduction and something does seem odd. Any idea what's going on?

jelbourn avatar Oct 27 '17 18:10 jelbourn

@jelbourn I did some digging and this appears to be caused by the row and header view containers being cleared in the CdkTable ngOnDestroy method. I was able to fix the issue by moving the view container clear calls inside of a debounced ngZone.onStable event emitter. Not sure if this is a great solution, but I couldn't find any "all animations complete" event emitters in the Angular API. I'll submit my changes as a PR if you want to take a look.

Another possible solution would be to allow consumers of DataSource to return an observable from the disconnect method and only clear the view containers when it emits to give the consumer control of the table destruction.

brandom avatar Oct 28 '17 20:10 brandom

Zone stable seems like a reasonable point right now. @matsko do you have any other suggestions?

jelbourn avatar Oct 29 '17 18:10 jelbourn

@brandom feel free to open a PR and mention @andrewseguin

jelbourn avatar Oct 29 '17 18:10 jelbourn

any update on this ?

hanyu-natsu avatar Jan 19 '18 14:01 hanyu-natsu

Any updates on this issue?

francesconi avatar Nov 15 '18 15:11 francesconi

Guuuys! We need thiiis)

Niaro avatar Dec 13 '18 14:12 Niaro

This is causing issues on our project. Be great to get a fix for this soon.

Pastafarian avatar Feb 11 '19 15:02 Pastafarian

It's a critical issue. Now I can't use router animation with components with table. Because table dissapears when animation starts. Fix it, please.

NZainchkovskiy avatar May 07 '19 11:05 NZainchkovskiy

@crisbeto cc @devversion cc @jelbourn cc @andrewseguin cc

Niaro avatar May 07 '19 11:05 Niaro

It's still an open issue and makes router animations very unpleasant when using this component...

RPicster avatar Jun 27 '19 20:06 RPicster

Any updates?

seopei avatar Aug 14 '19 21:08 seopei

As a workaround I did like so: export const rowAnimation = trigger('rowAnimation', [ transition('* => void', [ animate('0ms', style({ display: 'none'})) ]) ]); And then I applied it to mat-header-row and mat-row like this: <mat-header-row @rowAnimation *matHeaderRowDef="columnsToDisplay"></mat-header-row> <mat-row @rowAnimation *matRowDef="let row; columns: columnsToDisplay"></mat-row>

Ancient74 avatar Sep 30 '19 15:09 Ancient74

Issue reported in 2017 and still no proper fix :(

BazylPL avatar Jan 19 '20 22:01 BazylPL

I'm using the table with expandable rows and I can see some design glitches while transitioning between routes and I'm pretty sure that that's because of this issue.

TaridaGeorge avatar Feb 26 '20 00:02 TaridaGeorge

:(

DanielsJR avatar Mar 31 '20 20:03 DanielsJR

+1

Please fix, this is still an issue.

I make heavy use of mat-table and routing animations are pointless now.

DutchKevv avatar May 26 '20 19:05 DutchKevv

As a workaround I did like so: export const rowAnimation = trigger('rowAnimation', [ transition('* => void', [ animate('0ms', style({ display: 'none'})) ]) ]); And then I applied it to mat-header-row and mat-row like this: <mat-header-row @rowAnimation *matHeaderRowDef="columnsToDisplay"></mat-header-row> <mat-row @rowAnimation *matRowDef="let row; columns: columnsToDisplay"></mat-row>

this is a good solution to make the bug invisible, but it requires extra work every time you want to use a table and animate routing thanks @Ancient74

jarenasmuller avatar Jul 31 '20 15:07 jarenasmuller

no fixes have been released yet ?

@Ancient74 's workaround didn't work for me...

As a workaround I did like so: export const rowAnimation = trigger('rowAnimation', [ transition('* => void', [ animate('0ms', style({ display: 'none'})) ]) ]); And then I applied it to mat-header-row and mat-row like this: <mat-header-row @rowAnimation *matHeaderRowDef="columnsToDisplay"></mat-header-row> <mat-row @rowAnimation *matRowDef="let row; columns: columnsToDisplay"></mat-row>

kamil-hammouche avatar Oct 30 '20 15:10 kamil-hammouche

As a workaround I did like so: export const rowAnimation = trigger('rowAnimation', [ transition('* => void', [ animate('0ms', style({ display: 'none'})) ]) ]); And then I applied it to mat-header-row and mat-row like this: <mat-header-row @rowAnimation *matHeaderRowDef="columnsToDisplay"></mat-header-row> <mat-row @rowAnimation *matRowDef="let row; columns: columnsToDisplay"></mat-row>

This worked for me as a workaround, but the issue still exists in version 11+.

Abasz avatar Dec 26 '20 09:12 Abasz

As a workaround I did like so: export const rowAnimation = trigger('rowAnimation', [ transition('* => void', [ animate('0ms', style({ display: 'none'})) ]) ]); And then I applied it to mat-header-row and mat-row like this: <mat-header-row @rowAnimation *matHeaderRowDef="columnsToDisplay"></mat-header-row> <mat-row @rowAnimation *matRowDef="let row; columns: columnsToDisplay"></mat-row>

This worked for me as a workaround, but the issue still exists in version 11+.

How did it work for you ? I applied it like this

my-component.html <tr mat-header-row @rowAnimation *matHeaderRowDef="columns"></tr> <tr mat-row @rowAnimation *matRowDef="let row; columns: columns;"></tr>

my-component.ts import { rowAnimation } from '../../../assets/animations/table-row.animation'; @Component({ selector: 'mycomponent', animations: [rowAnimation] })

and it doesn't work

kamil-hammouche avatar Dec 28 '20 08:12 kamil-hammouche

As a workaround I did like so: export const rowAnimation = trigger('rowAnimation', [ transition('* => void', [ animate('0ms', style({ display: 'none'})) ]) ]); And then I applied it to mat-header-row and mat-row like this: <mat-header-row @rowAnimation *matHeaderRowDef="columnsToDisplay"></mat-header-row> <mat-row @rowAnimation *matRowDef="let row; columns: columnsToDisplay"></mat-row>

This worked for me as a workaround, but the issue still exists in version 11+.

How did it work for you ? I applied it like this

my-component.html <tr mat-header-row @rowAnimation *matHeaderRowDef="columns"></tr> <tr mat-row @rowAnimation *matRowDef="let row; columns: columns;"></tr>

my-component.ts import { rowAnimation } from '../../../assets/animations/table-row.animation'; @Component({ selector: 'mycomponent', animations: [rowAnimation] })

and it doesn't work

Did you register the animation trigger in the my-component.ts like the below:

@Component({
    selector: "my-component",
    templateUrl: "./my-component.html",
    animations: [rowAnimation]
})

Abasz avatar Dec 28 '20 17:12 Abasz

As a workaround I did like so: export const rowAnimation = trigger('rowAnimation', [ transition('* => void', [ animate('0ms', style({ display: 'none'})) ]) ]); And then I applied it to mat-header-row and mat-row like this: <mat-header-row @rowAnimation *matHeaderRowDef="columnsToDisplay"></mat-header-row> <mat-row @rowAnimation *matRowDef="let row; columns: columnsToDisplay"></mat-row>

This worked for me as a workaround, but the issue still exists in version 11+.

How did it work for you ? I applied it like this my-component.html <tr mat-header-row @rowAnimation *matHeaderRowDef="columns"></tr> <tr mat-row @rowAnimation *matRowDef="let row; columns: columns;"></tr> my-component.ts import { rowAnimation } from '../../../assets/animations/table-row.animation'; @Component({ selector: 'mycomponent', animations: [rowAnimation] }) and it doesn't work

Did you register the animation trigger in the my-component.ts like the below:

@Component({
    selector: "my-component",
    templateUrl: "./my-component.html",
    animations: [rowAnimation]
})

Yes I did

kamil-hammouche avatar Dec 28 '20 18:12 kamil-hammouche

I am not sure whether its relevant or not, but I use mat-header-row and mat-row and not the native html tr with the attributes. Also I use square brackets with the animation directive (but this should not be relevant either).

Abasz avatar Dec 28 '20 18:12 Abasz

Unfortunately there is no ideal solution for this issue on our end. The framework should be handling this case in its animations module to ensure that the clear does not remove elements that are part of an animation.

andrewseguin avatar Jul 19 '22 18:07 andrewseguin

Proposed workaround doesn't seem to have any effect, have you figured out why it doesn't work for you @kamil-hammouche? I'm using mat-header-row and mat-row just as @Abasz and it still doesn't work.

fxck avatar Dec 14 '23 16:12 fxck

Ah, it looks like it has to be on the *matRowDef element when you are using that.

fxck avatar Dec 14 '23 16:12 fxck