简体   繁体   中英

Angular 5 RouterLink does not work with same path but different parameters

I have a anchor element with a RouterLink element that takes parameters. The parameters are necessary in order to navigate to the correct page. Now the router link works when I navigate the page from a different path. For instance my router module looks like this:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { MoviesComponent } from './movies/movies.component';
import { MovieReviewComponent } from './movie-review/movie-review.component';
import { LoginComponent } from './login/login.component';
import { AdminComponent } from './admin/admin.component';
const routes: Routes = [
  { path: '', component: MoviesComponent },
  { path: 'movies', component: MoviesComponent },
  { path: 'movies/:movieTitle/:year', component: MovieReviewComponent },
  { path: 'login', component: LoginComponent },
  { path: 'admin', component: AdminComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

And I have a navigation component located outside the router-outlet like this:

<app-navigation></app-navigation>
<app-messages></app-messages>
<div id="main-layout" class="row p-3">
  <section class="col-12 col-xm-12 col-md-3">hi</section>
  <section class="col-12 col-xm-12 col-md-6">
    <router-outlet></router-outlet>
  </section>
  <section class="col-12 col-xm-12 col-md-3">lo</section>
</div>

My navigation has a search bar that uses RouterLink to route to path 'movies/:movieTitle/:year' and works as long as I'm coming from a path that isn't like 'movies/:movieTitle/:year' . If the paths are similar angular will not rerender even if the movieTitle and year arguments are different.

For example if I'm at home '/' or 'movies' I can use the navbar to successfully go to 'movies/The%20Dark%20Knight/2008' . But if I'm on 'movies/The%20Dark%20Knight/2008' I cannot use the navbar to go to '/movies/Taken/2008' . I believe this has to do with Angular trying to decrease rerendering for similar paths, but how do I get Angular to change views when the same path-type has different argument?

Extra Info

  • Even when the route fails to render a new view the path url changes in the browser and it is the same url for when the page change is successfull
  • I have angular navigation events in my navigation component. I can confirm that navigation starts and that there is no navigation error. Still have to test if it cancels or not.

Answer

As the answer says I needed to subscribe to the params. Previously when I was acquiring the params I was using a snapshot:

movieTitle = this.route.snapshot.paramMap.get('movieTitle');

Now I get the params directly and subscribe to them:

this.route.params.subscribe(params => {
      this.movieService.getMovie(params['movieTitle'], params['year'])
        .subscribe(movie => {
          this.movie = movie
        })
    })

Routes with empty path and no children should have pathMatch: 'full'

{ path: '', component: MoviesComponent, pathMatch: 'full' },

also the order of routes matters. More specific routes should come first:

{ path: 'movies/:movieTitle/:year', component: MovieReviewComponent },
{ path: 'movies', component: MoviesComponent },

If only route parameters change, but the route stays the same, Angular reuses the component. You need to subscribe to params to get notified about changes. The URL is still updated.

As @Günter Zöchbauer said in his answer, you need to subscribe to params to get notified about the changes. Here is how you can do that...

Suppose you are in OrderDetailComponent and you want to show the details of a specific order, the order with the id which exists in the URL like /orders/1 and properly shows the right order if the id changed like /orders/2 , /orders/3 , ... here is the code which performs that...

// order-detail.component.ts file

export class OrderDetailComponent implements OnInit {

    constructor(private activatedRoute: ActivatedRoute) { }

    ngOnInit() {
        // Subscribing to the route params is important as it fixes an issue as
        // Angular RouterLink may not work with same path but different params
        this.activatedRoute.params.subscribe(params => {
            console.log('URL Params', params);
            this.getOrder(+params.id);
        });
    }

    getOrder(id: number) {
        // Your code to get the order with the provided id...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM