Reputation: 9173
I have created a very basic angular 5 application.
I have a left menu which is always displayed (it is part of asp.net core2.0 mvc project skelton with bootstrap).
I have created 2 links in this menu:
<li>
<a [routerLink]='["/component/1"]'>Component 1</a>
</li>
<li>
<a [routerLink]='["/component/2"]'>Component 1</a>
</li>
As you can see, the 2 links points to the same route (same component). We just have the id which changes. Here is the route line in app.module.ts
{ path: 'component/:id', component: MyComponent, pathMatch: 'full' },
I have added some log in my component typescript class:
constructor()
{
console.log("constructor");
}
ngOnInit()
{
console.log("ngOnInit");
}
If i click on the first link, everything works great. But if i click to second link, my component is not reloaded. There are no calls to constructor or ngOnInit. If i click on another link which loads another component and then return to the second link, it works.
What i want to do is how can i force angular to reload component when i click on a link which points to the same component than the one actually displayed.
Thanks
Upvotes: 20
Views: 24460
Reputation: 3462
The answer by Frederick Montiel was helpful to me but uses a now deprecated syntax, so here is a version for Angular 16:
Implement a RouteReuseStrategy
:
import { BaseRouteReuseStrategy } from '@angular/router';
import { Injectable } from '@angular/core';
@Injectable()
export class NoRouteReuse extends BaseRouteReuseStrategy {
shouldReuseRoute = () => false;
}
And use it in your main.ts
:
import { RouteReuseStrategy } from '@angular/router';
import { NoRouteReuse } from '@config/no-route-reuse';
...
providers: [
...,
{ provide: RouteReuseStrategy, useClass: NoRouteReuse }
]
...
Upvotes: 2
Reputation: 101
Use
ngOnInit(): void {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}
Upvotes: 7
Reputation: 106
The answer by Deborah works best for your case where we only have to look for changes in the queryParams.
For anyone else, if your project really requires re-rendering a component as mine did(maybe you require to call ngOninit to reevaluate something), it can be done with
constructor(private router: Router){
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function(){
return false;
}
this.router.events.subscribe((evt) => {
if (evt instanceof NavigationEnd) {
// trick the Router into believing it's last link wasn't previously loaded
this.router.navigated = false;
// if you need to scroll back to top, here is the right place
window.scrollTo(0, 0);
}
});
}
The thread to the discussion where I found the solution : https://github.com/angular/angular/issues/13831
Upvotes: 2
Reputation: 60596
Normally in this case, you don't reload the component. Rather, you watch for changes in the required route parameter and proceed accordingly.
In my application, I use something like this:
constructor(private route: ActivatedRoute) { }
ngOnInit(): void {
this.route.params.subscribe(
params => {
const id = +params['id'];
this.getMovie(id);
}
);
}
This code catches ever change to the route parameter and causes my getMovie
method to be executed every time the route parameter changes.
For a complete example, check out: https://github.com/DeborahK/MovieHunter
Upvotes: 29