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

Multiple ShellComponent instance #109

Closed
luniks opened this issue Jul 26, 2017 · 5 comments
Closed

Multiple ShellComponent instance #109

luniks opened this issue Jul 26, 2017 · 5 comments

Comments

@luniks
Copy link

luniks commented Jul 26, 2017

I'm submitting a...


[ x ] Bug report
[   ] Feature request
[   ] Documentation issue or request

Current behavior

When you navigate to a new route in your application, a new instance of ShellComponent is created. So if you have a custom component in ShellComponent template (e.g: SidebarComponent), current state of your component is lost on route switching.

The above picture show router tree of an Angular application generated with ngx-rocket. Children routes of feature modules are not shared by ShellComponent:
router-tree-ngx-rocket

Expected behavior

Have a single ShellComponent for overall feature modules routes.

Minimal reproduction of the problem with instructions

  1. Generate a new project.
  2. Add console.log('*****INIT*****') in ngOnInit() method of ShellComponent.
  3. Start lite server and open browser console.
  4. Navigate on http://localhost:4200 and switch between "Home" and "About" pages.

Environment


Angular version: 4.3.1
ngx-rocket generator version: 1.3.2
@sinedied
Copy link
Member

Thanks for the nice issue template and the complete context information!
This is effectively a bug as the ShellComponent is expected to persist during child navigation.
I expected it to be the default, but saw numerous issue on the Angular repo about this so I'm not sure. I would prefer avoiding using a custom RouteReuseStrategy for this since it seems a pretty basic use case, but we'll see.

@luniks
Copy link
Author

luniks commented Jul 27, 2017

Your welcome !
I have done an ugly workaround for my project. For now it's OK but if I have free time, I will try to implement a cleaner solution an submit a PR on the subject. Suggestions on this are welcomed !

Some ideas:

  • as you mention, use a custom RouteReuseStrategy
  • use this.router.resetConfig(routes) method to dynamically configure routing strategy
  • use a custom factory to provide children routes during routing modules injection

For the third solution, the routing feature module could look like this:


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

@NgModule({
  imports: [RouterModule.forChild([])],
  exports: [RouterModule],
  providers: [
    {
      provide: ROUTES,
      useFactory: (provideRoutesWithShell),
      multi: true
    }
  ],
  entryComponents: [ ... ] // provide routed components here
})

You might also look the @ngx-i18n-router/core project: they use a custom routing module to dynamically translate application routes.

For now, I haven't a clear idea of what is the best solution...

@sinedied
Copy link
Member

sinedied commented Jul 27, 2017

I submitted an issue on Angular repo since it is not clear whether it is intended or not: angular/angular#18374

As for your ideas, the 3rd seems the cleanest one:

use a custom factory to provide children routes during routing modules injection

Thought I'm not sure how this may play with router lazy loading.

The routes using withShell method should then not be registered right away but stored to be provided once then?

@luniks
Copy link
Author

luniks commented Jul 28, 2017

I prefer the third solution too! But you need to play with Dependency Injection and I've not a clear idea of what is the best way to do it.

The routes using withShell method should then not be registered right away but stored to be provided once then?

Without a custom DI, the ugly solution is to use a shell-routing.module.ts to defined all feature routes and provide them only once (you can keep the declaration of your routes somewhere in your feature directory and export it).

It seems that you can't dynamically append child routes with Angular router. The only way is to do it at runtime (you register somehow your feature routes and use the resetConfig method to update dynamically your router).

Maybe there is other solutions... I would like to keep a dedicated routing module by feature. We'll see the answer of the Angular team on the issue!

@sinedied
Copy link
Member

I have asked for updates on the angular issue, since this issue is becoming quite old and still as problematic.

I have tested successfully implementing a custom RouteReuseStrategy and it works. While it's not my preferred solution, it has the advantage of being simple, easy to revert if Angular comes around it someday in the future and it compatible with lazy loading.

@sinedied sinedied moved this from Backlog to In Progress in ngX-Rocket backlog for all repos Nov 27, 2017
@sinedied sinedied moved this from In Progress to Done, Unreleased in ngX-Rocket backlog for all repos Nov 27, 2017
@sinedied sinedied moved this from Done, Unreleased to Released in ngX-Rocket backlog for all repos Nov 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
ngX-Rocket backlog for all repos
  
Released/Processed
Development

No branches or pull requests

2 participants