I am currently writing my first Angular 2 Application. I have an OverviewComponent which has the following simple template:
Use this on your constructor()
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
hope this will help.
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);
}
});
}
I don't know whether there is an answer to the problem similar to the one I'm going to propose right here, so I'll do it anyway:
I managed to achieve a 'fake' reload the following way.
What I basically did is creating a Component which redirects me to the 'real' component I want to use:
@Component({
selector: 'camps-fake',
template: ''
})
export class FakeComponent implements OnInit {
constructor(private _router:Router,
private _route:ActivatedRoute)
{ }
ngOnInit() {
let id:number = -1;
this._route.params.forEach((params:Params) => {
id = +params['id'];
});
let link:any[] = ['/details', id];
this._router.navigate(link);
}
}
So by selecting a list item the router will navigate to /fake/:id
which just extracts the id from the URL and navigates to the 'real' component.
I know there might be an easier, or more fancy way, but I think this solution works pretty well since the fake doesn't really attract attention. Just the 'flashing' when the page reloads is a negative aspect but as far as my css knowledge reaches there might be some transition to cover that.
This is currently not directly supported. See also https://github.com/angular/angular/issues/9811
What you can do is something like
<div *ngIf="doShow" class="row">
<div class="col-lg-8">
<router-outlet></router-outlet>
</div>
<div class="col-lg-4">
<app-list></app-list>
</div>
</div>
doShow:boolean: true;
constructor(private _activatedRoute: ActivatedRoute, private _router:Router, private cdRef:ChangeDetectorRef) {
_router.routerState.queryParams.subscribe(
data => {
console.log('queryParams', data['st']);
this.doShow = false;
this.cdRef.detectChanges();
this.doShow = true;
});
}
(not tested)
An idiomatic approach could be to use Observables and the | asyc
pipe in your template.
(taken from https://medium.com/@juliapassynkova/angular-2-component-reuse-strategy-9f3ddfab23f5 - read more for details )
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/pluck';
@Component({
selector: 'app-detail-reusable',
template: `<p>detail reusable for {{id$| async}} param </p>`
})
export class DetailReusableComponent implements OnInit {
id$: Observable<string>;
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.id$ = this.route.params.pluck('id');
}
}
If you are fetching further details from a REST api, you can use switchMap
for example:
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/pluck';
@Component({
selector: 'app-detail-reusable',
template: `<ul><li *ngFor="let item of items$ | async">{{ item.name }}</li></ul>`
})
export class DetailReusableComponent implements OnInit {
items$: Observable<string[]>;
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.items$ = this.route.params.pipe(
pluck("id"),
switchMap(id => this.http.get<string[]>(`api/items/${id}`)) // or whatever the actual object type is
);
}
}
The | async
pipe will automatically subscribe and the id$
or items$
observable will update when the route parameter changes triggering an API data fetch (in the items$
case) and updating the view.
You can change the routeReuseStrategy directly at the component level:
constructor(private router: Router) {
// force route reload whenever params change;
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}
Likewise, the reuse strategy can be changed globally.
This does not necessarily address your problem directly but seeing how this question is the first search result for "angular 2 reload url if query params change" it might save the next person from digging through the github issues.