I've come across the same problem when trying to refresh a page when clicking on its associated button on the navbar.
As stated in the comments, onSameUrlNavigation
only runs guards and resolvers, but do not reinitialize components. The interesting part is that it also triggers a navigation.
So I created an abstract class that reacts to the NavigationEnd
event:
/**
* Abstract class that allows derived components to get refreshed automatically on route change.
* The actual use case is : a page gets refreshed by navigating on the same URL and we want the rendered components to refresh
*/
export abstract class AutoRefreshingComponent implements OnInit, OnDestroy {
public routerEventsSubscription: Subscription;
protected router: Router;
constructor() {
this.router = AppInjector.get(Router);
}
/**
* Initialization behavior. Note that derived classes must not implement OnInit.
* Use initialize() on derived classes instead.
*/
ngOnInit() {
this.initialize();
this.routerEventsSubscription = this.router.events.filter(x => x instanceof NavigationEnd).subscribe(res => {
this.initialize();
});
}
/**
* Destruction behavior. Note that derived classes must not implement OnDestroy.
* Use destroy() on derived classes instead.
*/
ngOnDestroy(): void {
this.routerEventsSubscription.unsubscribe();
this.destroy();
}
/**
* Function that allows derived components to define an initialization behavior
*/
abstract initialize(): void;
/**
* Function that allows derived components to define a destruction behavior
*/
abstract destroy(): void;
}
AppInjector refers to this:
import {Injector} from '@angular/core';
/**
* Allows for retrieving singletons using `AppInjector.get(MyService)` (whereas
* `ReflectiveInjector.resolveAndCreate(MyService)` would create a new instance
* of the service).
*/
export let AppInjector: Injector;
/**
* Helper to access the exported {@link AppInjector}, needed as ES6 modules export
* immutable bindings; see http://2ality.com/2015/07/es6-module-exports.html
*/
export function setAppInjector(injector: Injector) {
if (AppInjector) {
// Should not happen
console.error('Programming error: AppInjector was already set');
}
else {
AppInjector = injector;
}
}
And in the AppModule:
import { setAppInjector } from './app.injector';
// ...
export class AppModule {
constructor(private injector: Injector) {
setAppInjector(injector);
}
}
Then I made all of my needed components extend AutoRefreshingComponent
and implement needed functions.
Hope this late answer helps.