Redirect a route from a "childModule" to another "childModule" with Angular 2 ( 4.0)

Asked

Viewed 1,474 times

0

Hello, I’m working with Angular where I have a structure like this:

|-app
   |-fooModule (fooPage1, fooPage2)
   |-barModule (barPage1, barPage2)

These two modules are being loaded using lazyLoad in the route file as shown below:

app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
    { path: 'bar', loadChildren: './foo/foo.module#FooModule' },
    { path: ''   , loadChildren: './bar/bar.module#BarModule' }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

The module AppRoutingModule is loaded into the initial module of the project, the AppModule together with others, and both in foo how much in bar the same structure but, instead of loading modules with lazyLoad, I load components, like this:

example: foo-routing.module (bar-routing.module.ts has the same structure)

import { FooPage1Component } from './foo-page-1/foo-page-1.component';
import { FooPage2Component } from './foo-page-2/foo-page-2.component';

const routes: Routes = [
    { path: 'page2', component: FooPage2Component },
    { path: ''   , component: FooPage1Component }
];

My problem is that when I’m on the route www.meusite.com/page2 and try to force a routing to Barmodule, Angular does not remove the already loaded components from the Foopage2component. It’s like he didn’t update on <router-outlet>. The way I call another module can be seen in the Foopage2component:

foo-page-2.Component

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
    selector: 'foo-page-2',
    templateUrl: './foo-page-2.component.html',
    styleUrls: ['./foo-page-2.component.scss']
})
export class FooPage2Component {
    constructor(
        private router:Router
    ){
        // depois de 2 segundos, redirecione para o módulo bar na pagina 2
        setTimeout(()=> router.navigate(['../bar/page2']), 2000);
    }
}

When I compile the above code, and do the test, the result on my page when doing the redirect is like this:

structure rendered in browser

<html>
    <head>
    </head>
    <body>
        <app>
             <router-outlet></router-outlet>
             <foo-page-2></foo-page-2>
             <bar-page-2></bar-page-2>
        </app>
    </body>
</html>

So here’s the question: if I have 2 different modules that have their own routes and are dynamically loaded (with lazyLoad on loadChildren) how can I tell at the angle I want, from the Foopage2 component that is in Foomodule, redirect to a Barpage2 component in Barmodule?

Note: I’ve tried using the Router.navigate, Router.navigateByUrl, I tried to force the navigation by passing the parameters of Navigationextra.relativeTo and yet, it doesn’t work. Unfortunately my solution so far is being a (horrible) window.location.href = window.location.href.replace('/page2','/bar/page2);

Can someone help me?

2 answers

0


Since there was no kind of response and I also did not find a plausible solution on the internet, my solution was to create a service that is related to the AppComponent and listening to a custom event. This custom event simply triggers the array that references the Router needs to be able to redirect without leaving the angle, so all the redirect control is done by the main module independent of the child module that I use so:

Rootrouterredirect.ts class.

export class RootRouterRedirect {

    public constructor(redirect: string | string[]) {
        const event = new CustomEvent('rootRouterRedirect', { detail: [].concat(redirect) });
        window.dispatchEvent(event);
    }

}

And in my Appcomponent I attached a method that makes the Reader of that event, like this:

Appcomponent

import { Component, HostListener } from '@angular/core';
... outros imports 
@Component({
    selector: 'app',
    template: `
        <router-outlet></router-outlet>
    `
})
export class AppComponent {

    ... construtores e métodos

    @HostListener('window:rootRouterRedirect', ['$event'])
    private event(e): void {
        this.router.navigate(e.detail);
    }

}

Why do this?

Angular 2 allows multiple route files to be each in each module. These routes may have their redirects but, from what I could tell when it directed routes between modules loaded track lazyload as in the description of the problem, the structure routes cannot properly destroy all components, thus maintaining sections, tracks or in occasions the route itself without upgrade.

Now if whoever makes the call is the route that works over the RouterModule.forRoot(), this problem does not occur because it is that does the main treatment. Moreover, it seems that if the module does not is loaded (because it is a lazyload module) the sub-structure of the RouterModule.forChild() that is defined in it is not yet found, therefore cannot be referenced.

-2

Now I understand your code you’re making two separate modules!!!

Your app-routing.module.ts should be pointing to 2 other route modules:

  {
    path: 'admin',
    loadChildren: () => import('../app/modules/admin/admin.module').then(m => m.AdminModule),
    canActivate: [AdminGuard, AuthGuard],
  },
  {
    path: 'login',
    loadChildren: () => import('../app/pages/login/login.module').then(m => m.LoginModule),
    canActivate: [LoginGuard],
  },
  {
    path: '',
    loadChildren: () => import('../app/modules/user/user.module').then(m => m.UserModule)
  },

What your app-routing.module.ts should look like.:

  {
    path: "",
    component: UserComponent,
    children: [
      {
        path: "",
        loadChildren: () => import('./modules/user/pages/home/home.module').then(m => m.HomeModule),
        canActivate: [CheckEmailGuard]
      },
      {
        path: "sobre",
        loadChildren: () => import('./modules/user/pages/about/about.module').then(m => m.AboutModule),
        canActivate: [CheckEmailGuard]
      },
      {
        path: "conta",
        loadChildren: () => import('./modules/user/pages/account/account.module').then(m => m.AccountModule),
        canActivate: [LoginGuard]
      },
      {
        path: "alterar-usuario",
        loadChildren: () => import('./modules/user/pages/update-user-data/update-user-data.module').then(m => m.UpdateUserDataModule),
        canActivate: [AuthGuard, CheckEmailGuard]
      },
      {
        path: "config",
        loadChildren: () => import('./modules/user/pages/config/config.module').then(m => m.ConfigModule),
        canActivate: [AuthGuard, CheckEmailGuard]
      },
      {
        path: "cadastro",
        loadChildren: () => import('./modules/user/pages/register/register.module').then(m => m.RegisterModule),
        canActivate: [LoginGuard]
      },
      {
        path: "verificando-email",
        loadChildren: () => import('./modules/user/pages/checking-email/checking-email.module').then(m => m.CheckingEmailModule),
        canActivate: [AuthGuard, BlockCheckEmailGuard]
      },
      {
        path: "login",
        loadChildren: () => import('./modules/user/pages/login/login.module').then(m => m.LoginModule),
        canActivate: [LoginGuard]
      },
      {
        path: "carrinho",
        loadChildren: () => import('./modules/user/pages/cart/cart.module').then(m => m.CartModule),
        resolve: {
          cart: CartResolver
        },
        canActivate: [CheckEmailGuard]
      },
      {
        path: "produtos",
        loadChildren: () => import('./modules/user/pages/products/products.module').then(m => m.ProductsModule),
        canActivate: [CheckEmailGuard]
      },
    ]
  },
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [AdminGuard],
    children: [
      {
        path: "",
        redirectTo: "home",
        pathMatch: "full",
      },
      {
        path: "home",
        loadChildren: () => import('./modules/admin/pages/admin-home/admin-home.module').then(m => m.AdminHomeModule),
        canActivate: [AuthGuard]
      },
      {
        path: "users",
        loadChildren: () => import('./modules/admin/pages/admin-home/admin-home.module').then(m => m.AdminHomeModule),
        canActivate: [AuthGuard]
      },
      {
        path: "products",
        loadChildren: () => import('./modules/admin/pages/admin-products/admin-products.module').then(m => m.AdminProductsModule),
        canActivate: [AuthGuard]
      },
      {
        path: "product",
        loadChildren: () => import('./modules/admin/pages/admin-product/admin-product.module').then(m => m.AdminProductModule),
        canActivate: [AuthGuard]
      }
    ]
  },
  {
    path: "**",
    redirectTo: '/',
    pathMatch: "full"
  }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.