Angular 2 reload route on param change

痞子三分冷 提交于 2019-11-29 21:22:27

As per the first final release, this is resolved.

Just pay much attention to correctly reset the state of the component when the parameter changes

this.route.params.subscribe(params => {
    this.param = params['yourParam'];
    this.initialiseState(); // reset and set based on new parameter this time
});

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.

Another alternative that should be added here is to provide a RouteReuseStrategy to your module.

providers: [
  {
    provide: RouteReuseStrategy,
    useClass: AARouteReuseStrategy
  }
]

The default behaviour of the router is to reuse the route if the configuration is the same (which is the case when only changing the :id param in this question). By changing the strategy to not reuse the route, the component will be reloaded, and you do not have to subscribe to route changes in the component.

An implementation of the RouteReuseStrategy could be like this:

export class AARouteReuseStrategy extends RouteReuseStrategy {
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  store(route: ActivatedRouteSnapshot, handle: {}): void {

  }
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  retrieve(route: ActivatedRouteSnapshot): {} {
     return null;
 }
 shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
   return false; // default is true if configuration of current and future route are the same
 }
}

I've written some about it here too:

https://pjsjava.blogspot.no/2018/01/angular-components-not-reloading-on.html

hGen

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.

Is possible to detect any change in the parameters received, in my case I load the information using a Resolve so I don't need the parameter (only detect if it change). This is my final solution:

public product: Product;
private parametersObservable: any;

constructor(private route: ActivatedRoute) {
}

ngOnInit() {
  this.parametersObservable = this.route.params.subscribe(params => {
    //"product" is obtained from 'ProductResolver'
    this.product = this.route.snapshot.data['product'];
  });
}

//Don't forget to unsubscribe from the Observable
ngOnDestroy() {
  if(this.parametersObservable != null) {
    this.parametersObservable.unsubscribe();
  }
}
user3728728

I solved it by using event, if the child component send a new link, and emit an event, then the parent can find the change and call to some reload function, which will reload the necessary data. Another option is to subscribe to the route parameters, and found when it change But I do think that the guys from angular2 should think about adding parameters to the router.navigate function, which can force the reload. (forceReload=true)

Ashutosh Kushawaha

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);
    }
});

}

Import Router in your Angular 7 project.

import { Router } from '@angular/router';

Create an object of the Router

constructor(private router: Router) {

}

Use routeReuseStrategy to detect router parameter change

ngOnInit() {
    this.router.routeReuseStrategy.shouldReuseRoute = () => {
      // do your task for before route

      return false;
    }
}

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)

this.route.paramMap.subscribe(params => {
  //fetch your new parameters here, on which you are switching the routes and call ngOnInit()
  this.ngOnInit();
 });

You just need to call ngOnInit() from inside the paramMap and it will initialise the whole page with newly loaded data.

Abdus Salam Azad

Use this on your constructor()

this.router.routeReuseStrategy.shouldReuseRoute = () => false;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!