Encountering the same issue of refreshing a page upon clicking its corresponding button on the navbar has been a challenge.
The state of the application in Angular remains unchanged when navigating to the same URL, causing no effect according to Angular's logic.
To address this issue, there is a workaround available through the onSameUrlNavigation option.
Although this option triggers guards and resolvers upon navigating to the same URL, activating it may not yield noticeable results.
To tackle this issue personally, I devised a custom workaround by creating a specific class:
/**
* Abstract class that enables derived components to automatically refresh upon route change.
* The intended use case is: updating a page by navigating to the same URL while ensuring rendered components are refreshed.
*/
export abstract class AutoRefreshingComponent implements OnInit, OnDestroy {
public routerEventsSubscription: Subscription;
protected router: Router;
constructor() {
this.router = AppInjector.get(Router);
}
/**
* Initialization behavior. Derived classes must avoid implementing OnInit directly.
* Instead, utilize initialize() in derived classes.
*/
ngOnInit() {
this.initialize();
this.routerEventsSubscription = this.router.events.filter(x => x instanceof NavigationEnd).subscribe(res => {
this.initialize();
});
}
/**
* Destruction behavior. Derived classes should not implement OnDestroy directly.
* Use destroy() in derived classes instead.
*/
ngOnDestroy(): void {
this.routerEventsSubscription.unsubscribe();
this.destroy();
}
/**
* Function for derived components to define initialization behavior
*/
abstract initialize(): void;
/**
* Function for derived components to define destruction behavior
*/
abstract destroy(): void;
}
AppInjector is referenced as follows:
import {Injector} from '@angular/core';
/**
* Enables retrieval of singletons using `AppInjector.get(MyService)` (compared to creating a new instance with `ReflectiveInjector.resolveAndCreate(MyService)`).
*/
export let AppInjector: Injector;
/**
* Tool for accessing the exported {@link AppInjector}, necessary since ES6 modules export immutable bindings; refer to http://2ality.com/2015/07/es6-module-exports.html
*/
export function setAppInjector(injector: Injector) {
if (AppInjector) {
// Error check
console.error('Programming error: AppInjector was already set');
}
else {
AppInjector = injector;
}
}
In your AppModule:
import { setAppInjector } from './app.injector';
// ...
export class AppModule {
constructor(private injector: Injector) {
setAppInjector(injector);
}
}
Ensure all required components extend AutoRefreshingComponent
.
In your situation:
@Component({
selector: 'app-user',
template: `
<input #box (keyup.enter)="onEnter(box.value)">
<div *ngIf="box.size > 0">
<app-order [value]="value"></app-order>
</div>`
})
export class UserComponent extends AutoRefreshingComponent {
value = '';
onEnter(value: string) {
this.value = value;
}
constructor() {
}
initialize() {
// Reset your box value
}
destroy() {
}
}
This approach might seem extensive for your current requirements, but it proves beneficial whenever you need to refresh a component during same URL navigation.
Feel free to reach out if you find this useful.