snippetjavascriptangularCritical
How to implement RouteReuseStrategy shouldDetach for specific routes in Angular 2
Viewed 0 times
angularshoulddetachhowforroutereusestrategyroutesspecificimplement
Problem
I have an Angular 2 module in which I have implemented routing and would like the states stored when navigating.
The user should be able to:
This is possible including
The question is:
How do I implement that the document should not be stored?
So the route path "documents"'s state should be stored and the route path "documents/:id"' state should NOT be stored?
The user should be able to:
- search for documents using a 'search formula'
- navigate to one of the results
- navigate back to 'searchresult' - without communicating with the server
This is possible including
RouteReuseStrategy. The question is:
How do I implement that the document should not be stored?
So the route path "documents"'s state should be stored and the route path "documents/:id"' state should NOT be stored?
Solution
Hey Anders, great question!
I've got almost the same use case as you, and wanted to do the same thing! User search > get results > User navigates to result > User navigates back > BOOM blazing fast return to results, but you don't want to store the specific result that the user navigated to.
tl;dr
You need to have a class that implements
About RouteReuseStrategy
By having asked this question, you already understand that RouteReuseStrategy allows you to tell Angular not to destroy a component, but in fact to save it for re-rendering at a later date. That's cool because it allows:
That last one is important if you would like to, say, leave a page temporarily even though the user has entered a lot of text into it. Enterprise applications will love this feature because of the excessive amount of forms!
This is what I came up with to solve the problem. As you said, you need to make use of the
TODO
First Make sure your project has @angular/router version 3.4.1 or higher.
Next, create a file which will house your class that implements
(don't worry about your TypeScript errors, we're about to solve everything)
Finish the groundwork by providing the class to your
The final piece is writing the class which will control whether or not routes get detached, stored, retrieved, and reattached. Before we get to the old copy/paste, I'll do a short explanation of mechanics here, as I understand them. Reference the code below for the methods I'm describing, and of course, there's plenty of documentation in the code.
So, we've seen the logic for storage, but what about navigating to a component? How does Angular decide to intercept your navigation and put the stored one in its place?
That's pretty much all the logic you need! In the code for
reuse-strategy.ts
`/**
* reuse-strategy.ts
* by corbfon 1/6/17
*/
import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';
/*
I've got almost the same use case as you, and wanted to do the same thing! User search > get results > User navigates to result > User navigates back > BOOM blazing fast return to results, but you don't want to store the specific result that the user navigated to.
tl;dr
You need to have a class that implements
RouteReuseStrategy and provide your strategy in the ngModule. If you want to modify when the route is stored, modify the shouldDetach function. When it returns true, Angular stores the route. If you want to modify when the route is attached, modify the shouldAttach function. When shouldAttach returns true, Angular will use the stored route in place of the requested route. Here's a Plunker for you to play around with.About RouteReuseStrategy
By having asked this question, you already understand that RouteReuseStrategy allows you to tell Angular not to destroy a component, but in fact to save it for re-rendering at a later date. That's cool because it allows:
- Decreased server calls
- Increased speed
- AND the component renders, by default, in the same state it was left
That last one is important if you would like to, say, leave a page temporarily even though the user has entered a lot of text into it. Enterprise applications will love this feature because of the excessive amount of forms!
This is what I came up with to solve the problem. As you said, you need to make use of the
RouteReuseStrategy offered up by @angular/router in versions 3.4.1 and higher.TODO
First Make sure your project has @angular/router version 3.4.1 or higher.
Next, create a file which will house your class that implements
RouteReuseStrategy. I called mine reuse-strategy.ts and placed it in the /app folder for safekeeping. For now, this class should look like:import { RouteReuseStrategy } from '@angular/router';
export class CustomReuseStrategy implements RouteReuseStrategy {
}
(don't worry about your TypeScript errors, we're about to solve everything)
Finish the groundwork by providing the class to your
app.module. Note that you have not yet written CustomReuseStrategy, but should go ahead and import it from reuse-strategy.ts all the same. Also import { RouteReuseStrategy } from '@angular/router';@NgModule({
[...],
providers: [
{provide: RouteReuseStrategy, useClass: CustomReuseStrategy}
]
)}
export class AppModule {
}
The final piece is writing the class which will control whether or not routes get detached, stored, retrieved, and reattached. Before we get to the old copy/paste, I'll do a short explanation of mechanics here, as I understand them. Reference the code below for the methods I'm describing, and of course, there's plenty of documentation in the code.
- When you navigate,
shouldReuseRoutefires. This one is a little odd to me, but if it returnstrue, then it actually reuses the route you're currently on and none of the other methods are fired. I just return false if the user is navigating away.
- If
shouldReuseRoutereturnsfalse,shouldDetachfires.shouldDetachdetermines whether or not you want to store the route, and returns abooleanindicating as much. This is where you should decide to store/not to store paths, which I would do by checking an array of paths you want stored againstroute.routeConfig.path, and returning false if thepathdoes not exist in the array.
- If
shouldDetachreturnstrue,storeis fired, which is an opportunity for you to store whatever information you would like about the route. Whatever you do, you'll need to store theDetachedRouteHandlebecause that's what Angular uses to identify your stored component later on. Below, I store both theDetachedRouteHandleand theActivatedRouteSnapshotinto a variable local to my class.
So, we've seen the logic for storage, but what about navigating to a component? How does Angular decide to intercept your navigation and put the stored one in its place?
- Again, after
shouldReuseRoutehas returnedfalse,shouldAttachruns, which is your chance to figure out whether you want to regenerate or use the component in memory. If you want to reuse a stored component, returntrueand you're well on your way!
- Now Angular will ask you, "which component do you want us to use?", which you will indicate by returning that component's
DetachedRouteHandlefromretrieve.
That's pretty much all the logic you need! In the code for
reuse-strategy.ts, below, I've also left you a nifty function that will compare two objects. I use it to compare the future route's route.params and route.queryParams with the stored one's. If those all match up, I want to use the stored component instead of generating a new one. But how you do it is up to you!reuse-strategy.ts
`/**
* reuse-strategy.ts
* by corbfon 1/6/17
*/
import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';
/*
Context
Stack Overflow Q#41280471, score: 313
Revisions (0)
No revisions yet.