1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

Angular Router - how to destroy old component immediately when routerLink changes

Discussão em 'Angular' iniciado por Tovar, Outubro 7, 2024 às 12:43.

  1. Tovar

    Tovar Guest

    In Angular, when a routerLink triggers a route change, the old component is destroyed basically at the same time as the new component's initialization.

    This is being a problem for me because I want to show a spinner after the old component is destroyed and before the new component is built -- this is relevant when a component/module is lazy-loaded. Since the old component is only destroyed as late as the new component is being built, my current spinner is just laying over the old component while the new component is loaded.

    So is there a way to config the router so it destroys the old component as soon as routerLink is triggered?

    I should also mention that I don't want to hide the router-outlet in any way because I'm also applying animations to the entering/leaving components, including the spinner. I'm using Tailwind too.

    Here's what that code is looking like, if it matters:

    @Component({
    styles: `
    :host ::ng-deep router-outlet + * { // target the routed components and the spinner
    &, & + * {
    @apply absolute top-0 left-0 w-full;
    }
    }
    `,
    animations: [
    trigger('routeAnimations', [
    transition('* <=> *', [
    query(':enter, :leave', [ style({
    position: 'absolute', left: 0, width: '100%', overflow: 'hidden',
    }) ], { optional: true }),
    group([
    query(':enter', [
    style({ opacity: '0' }),
    animate(animation, style({ opacity: '1' })),
    ], { optional: true }),
    query(':leave', [
    style({ opacity: '1' }),
    animate(animation, style({ opacity: '0' })),
    ], { optional: true }),
    ]),
    ]),
    ]),
    ],
    })
    export class MyComponent {
    #router = inject(Router);

    protected route = new Subject<string>();
    #lazyLoadingStarted$ = this.#router.events.pipe(
    filter(v => v instanceof RouteConfigLoadStart),
    map(() => '__lazy_loading__'),
    );
    protected routingState = toSignal(this.#lazyLoadingStarted$.pipe(mergeWith(this.route)));
    }


    <div [@routeAnimations]=routingState() class="relative h-full w-full">
    <router-outlet #outlet="outlet" (activate)="route.next(outlet.activatedRoute.snapshot.url[0]?.path || '')"/>
    @if (routingState() === '__lazy_loading__') {
    <div class="h-full">
    <div class="absolute-center">
    <mat-spinner/>
    </div>
    </div>
    }
    </div>

    Continue reading...

Compartilhe esta Página