I have a navbar component which has one routerLink
<p>
<a routerLink="/user">User</a>
</p>
and a nested component under UserComponent to which I am passing value
@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 implements OnInit {
value = '';
onEnter(value: string) {
this.value = value;
}
constructor() {
}
ngOnInit() {
}
}
OrderComponent
@Component({
selector: 'app-order',
template:`{{id}}`
})
export class OrderComponent implements OnInit {
@Input() id:String;
constructor() { }
ngOnInit() {
}
}
Now when I enter user link I get my view with link and my passed value. When I click the link again, I get the same page with value. How can I change this behavior so that when I click on the route button again I get the input without the passed value?
I've come across the same problem when trying to refresh a page when clicking on its associated button on the navbar.
Angular states that a navigation on the same URL has no effect since the state of the application is represented by its current URL.
There is a workaround for this : onSameUrlNavigation
Unfortunately, this option only allows the guards and resolvers to run again when navigating to the same URL, so if you activate it you'll notice...nothing at all!
So I created my own workaround with this class:
/**
* 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 your AppModule:
import { setAppInjector } from './app.injector';
// ...
export class AppModule {
constructor(private injector: Injector) {
setAppInjector(injector);
}
}
Then make all of your needed component extend AutoRefreshingComponent
.
In your case:
@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 may be overkill for what you want to achieve, but it will be useful every time you want to refresh a component on same URL navigation.
Let me know if this helps.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments