20

Angular Community!

I'm currently rewriting AngularJS app to Angular 2. I want to solve problem which could be described as: route tabs + child routes.

So, basically Router in Angular 2 destroys inactive components (my tabs!). The problem is I don't want this behaviour. Reason is I have some components like charts and data grid and want to switch between them fast, I don't want to recreate them.

I have found some workaround to persist my tabs while having routes but using this approach I don't know how to implement child routes. I'd like to also have a solution depth-independent (meaning: working more levels deeper) because I have more subtabs that need to be persisted.

The workaround is: I have put some empty component to routes and instantiate tabs myself hiding them with [hidden] property:

app.ts:

@Component({ /*...*/ })
@RouteConfig([
    {path: '/**', redirectTo: ['Dashboard']},

    {path: '/dashboard', name: 'Dashboard', component: EmptyRoute},
    {path: '/products/...', name: 'Products', component: EmptyRoute},
    {path: '/sales', name: 'Sales', component: EmptyRoute},
    {path: '/reports', name: 'Reports', component: EmptyRoute},
])
export class App {
    constructor(private router: Router) {
    }

    public isRouteActive(route) {
        return this.router.isRouteActive(this.router.generate(route))
    }
}

app.html:

<dashboard [hidden]="!isRouteActive(['/Dashboard'])"></dashboard>
<products-management [hidden]="!isRouteActive(['/Products'])"></products-management>
<sales [hidden]="!isRouteActive(['/Sales'])"></sales>
<reports [hidden]="!isRouteActive(['/Reports'])"></reports>
Namek
  • 1,182
  • 1
  • 13
  • 28
  • If anyone would be interested in some partial solution: https://github.com/angular/angular/issues/6634 – Namek Jan 24 '16 at 16:52
  • I had this problem myself, and found the answer to my own question here: http://stackoverflow.com/a/36100138/2972 – MartinHN Mar 19 '16 at 10:13
  • @MartinHN have you tested it for parameterized hierarchies? My test plnkr: http://plnkr.co/edit/MMy3azc4ksQOH6ezZIG5?p=preview - click Product 1, then Product 2, then Product 1, text on the bottom is missing. Couldn't find solution but Router definetely shouldn't manage lifecycle of components. CanReuse doesn't work as we would expect. It just compares between components of same type, probably on same route level. I have lost some time debugging Angular 2 and I believe that Router needs redesign - custom Outlet won't do - or maybe for some cases where hierarchy doesn't play a role – Namek Mar 20 '16 at 12:00
  • Hi @Namek -- I know this is a bit old -- do you have an update on best way to do this using RC5? – jlee Aug 23 '16 at 23:40
  • Sorry, for the moment, I threw away routing because of this. But please follow referenced github issues from #6634, linked in above comment. Especially issue #5275 – Namek Aug 24 '16 at 10:37
  • 1
    I may add that I resolved my issue without Routing and I've described it here https://www.namekdev.net/2017/05/angular-2-my-solution-for-dynamic-tabs/ – Namek May 19 '17 at 12:57

1 Answers1

1

I understand you have two different questions:

1- How to prevent the destruction of the component when you leave it. 2- implementing child routes.

1) For now Angular doesn't have convenient way to do this. We would apreciate it if they were a life cycle hook called like canDestroy().

Anyway you can do this either using non routable tabs OR just store your data on a higher component that doesn't get destroyed.

2) For the child routes I'll just put 2 examples:

Ex1: regular child routing

const AdminRoutes: Routes = [
{
  path: '',
  component: AdminComponent,
  children: [
    {
      path: 'users',
      component: UsersComponent,
      children: [
        { path: 'acces',  component: AccesComponent, data: { preload: true} },
        { path: 'roles',  component: RolesComponent, data: { preload: true} },
        { path: '',   redirectTo: '/admin/users/acces', pathMatch: 'full' },
        { path: '**', redirectTo: '/admin/users/acces', pathMatch: 'full' },
      ],
      data: { preload: true}
    },
    { path: '',   redirectTo: '/login', pathMatch: 'full' },
    { path: '**', redirectTo: '/login', pathMatch: 'full' }
  ]
},

EX2: When the child routes belongs to another module

Code for higher module

`

    const appRoutes: Routes = [
  { path: 'login',  component: LoginComponent, data: { preload: true} },
  {
    path: 'admin',
    loadChildren: 'app/modules/admin/admin.module#AdminModule',
    canActivate: [AuthGuardService],
    data: { preload: true}
  },
  { path: '',   redirectTo: '/login', pathMatch: 'full' },
  { path: '**', redirectTo: '/login', pathMatch: 'full' }

`

Code for child routes in their own module

`

const AdminRoutes: Routes = [
{
  path: '',
  component: AdminComponent,
  children: [
    {
      path: 'users',
      component: UsersComponent,
      children: [
        { path: 'acces',  component: AccesComponent, data: { preload: true} },
        { path: 'roles',  component: RolesComponent, data: { preload: true} },
        { path: '',   redirectTo: '/admin/users/acces', pathMatch: 'full' },
        { path: '**', redirectTo: '/admin/users/acces', pathMatch: 'full' },
      ],
      data: { preload: true}
    },
    { path: '',   redirectTo: '/login', pathMatch: 'full' },
    { path: '**', redirectTo: '/login', pathMatch: 'full' }
  ]
},

`

Taha Zgued
  • 1,088
  • 12
  • 18