Angular 2 reload route on param change

后端 未结 13 1094
小鲜肉
小鲜肉 2020-12-07 13:15

I am currently writing my first Angular 2 Application. I have an OverviewComponent which has the following simple template:

相关标签:
13条回答
  • 2020-12-07 13:27

    Use this on your constructor()

    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
    
    0 讨论(0)
  • 2020-12-07 13:29

    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);
        }
    });
    
    }
    
    0 讨论(0)
  • 2020-12-07 13:32

    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.

    0 讨论(0)
  • 2020-12-07 13:40

    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)

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-07 13:46

    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.

    0 讨论(0)
提交回复
热议问题