Solvedangular Router does not reuse component when switching between different Routes that use the same component.

I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

2 or more route declarations point to the same component. If a different route matches to the same component, the DOM and component are thrown away.

/hero/1 -> /hero/2 no issue, component stays around
/hero/1 -> /hero/1/powers component is disposed of

Expected behavior

I should be able to change my route to anything and as long as it results in the same component being in the same routerOutlet, it should stay around. This is in reference to some comments in #9811

Minimal reproduction of the problem with instructions

In this example, my component should never be discarded and re-inited
https://plnkr.co/edit/T7K4TfcTdHoqJ7HaFByS?p=preview

What is the motivation / use case for changing the behavior?

in the above example, powers could be a tab name I want to cue off of. It could be something I ngIf on, or any other number of things.

Please tell us about your environment:

MacOS, Sublimet Text, Npm

  • Angular version: 2.0.X

    2.1.1

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

    all

  • Language: [all | TypeScript X.X | ES6/7 | ES5]
    all

  • Node (for AoT issues): node --version =
    6.5.0

43 Answers

✔️Accepted Answer

Hi @dewwwald, I think you might be interested how I achieved this goal by using custom router reuse strategy:

export class CustomRouteReuseStrategy extends RouteReuseStrategy {
    public shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
    public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
    public shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
    public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
    public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return (future.routeConfig === curr.routeConfig) || future.data.reuse;
    }
}

And setting data: { reuse: true } for component route that should be reused. I described the details here: https://stackoverflow.com/questions/44875644/custom-routereusestrategy-for-angulars-child-module/44876414#44876414.

Other Answers:

Sir, when you have a complex application, enterprises invest millions of dollars to build it.

One can build "some kind of application" with it. That kind of people are those who are just learning Angular2 or doing a proof of concepts.

But a framework that disregards such a basic tenet, needs to first realize the importance of what is missing.

What you are missing is that "Not destroying the components" is how applications are built today. You are adopting the approach of destroying - and expecting developers to waste their time to recreate that state, which is unnecessary and intrusive to the UI architecture. Why are you doing this? Is it just convenient for yourself. What would be the cost of this? Especially, when mainstream community finds out, then they may use the third party UI-Router. Only a novice developer will go to the work arounds, you mentioned. Seasoned UI developers can visualize the ditch that has been dug. So, the question is why is this not high priority? Angular2 is still in early stages. Later, the more people look at it, the more people will mock it. This is very fundamental to survival of the Router.

It is absolutely not about little inconvenience. One has to design every bit of the application differently with this serious limitation and one may run into issues that can never be implemented with the current approach.

@jamesmfriedman this is a very serious issue, which the router team is mistaking for a minor one. Can't believe that they have gone so complex that they can't provide a simple interface and invoke it with the active route. Any experienced single page app developer will be revolted to see the components being destroyed like this. The app is creating and destroying components all the time, as you navigate - for no obvious reason (because Framework demands that). Really funny!!! This is amateurish decision.

"Just a thought, the activate route could be an observable, like RouteParams, so you could still inject it, but you can watch it in case it changes." @jamesmfriedman This is a great suggestion.

Thanks for mentioning UI Router. If push comes to shove, I am glad that there is UI-Router project.

@zoechi Thank you for the great sources, I have been reading a lot of github issues and been through a ton of commits to the point I lost track of whether the feature I need is properly implemented or not. Turns out it is, and here is a demo of that for anybody that finds it hard to implement.

To use it just add a reuse: true boolean in your router configuration.

More Issues: