角7路由到相同的组件,但不同的参数不起作用

时间:2019-02-11 09:33:09

标签: angular angular-router

我有2个路由器插座:侧边栏和默认的一个。

 {path: 'motor/:id', component: MotorComponent}

从侧边栏插座中,我有一些指向默认路由器插座的路由器链接,它们针对相同的组件(MotorComponent)但参数不同。

this.router.navigate(['./', {outlets: {primary: ['motor', 
id]}}]);

如果我单击一个,则会加载相应的组件,但是如果我单击另一个路由器链接,则不会加载正确的组件。参数会在网址中更改。

我读到这是一个常见问题。我尝试了一种重用策略,但我认为该策略实施得不好,没有任何反应。

我想单击针对同一组件但参数不同的不同路由器链接,即使该组件是同一组件,该组件也会加载。

这是我的ngOninit,我在其中订阅路由参数,保存该ID,然后从服务中获取新对象。

motor: MotoarePrincipale;
id: number;

ngOnInit() {
this.route.params.subscribe(
  (params: Params) => {
    this.id = +params['id'];
  }
);
this.masinaService.getMotorByMotorId(this.id).subscribe(data => {
  this.motor = data;
});

2 个答案:

答案 0 :(得分:2)

对于角度7(我仅在此版本上尝试过),可以在组件中使用路由重用策略:

constructor(private routerR: Router) {

    // this is for routerLink on same component when only queryParameter changes
    this.routerR.routeReuseStrategy.shouldReuseRoute = function () {
      return false;
    };
  }

答案 1 :(得分:0)

您需要使用

private route: ActivatedRoute,
private router: Router

您需要监听URL中ID的更改,最后将地图切换为正确的ID。从RXJS Observables in Angular - Ward Bell & Sander Ellis

看这个例子

这里是一个实现示例,您可以在不刷新页面的情况下根据其ID看电影:

TS:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';

import { Observable, Subscription } from 'rxjs';
import { switchMap, tap, map } from 'rxjs/operators';

import { Movie } from '../../samples/sw-interfaces';
import { FilmService } from './film.service';

@Component({
  selector: 'app-movie',
  template: `
      <h1>Routed Movie Component</h1>

      <div>
        <button (click)="previousMovie()">Previous</button>

        <div *ngIf="currentMovie$ | async as movie; else noMovie"  class="title">
            ({{movie.id}}) {{ movie.title }}
        </div>

        <ng-template #noMovie>
            <div class="missing">No Movie</div>
        </ng-template>

        <button (click)="nextMovie()">Next</button>
      </div>
    `,
  providers: [FilmService],
  styleUrls: ['./movie.component.css']
})
export class MovieComponent implements OnInit, OnDestroy {
  currentMovie$: Observable<Movie>;

  currentId: number;
  nextId: number;
  previousId: number;

  routerEventsSubscription: Subscription;

  constructor(
    private filmService: FilmService,
    private route: ActivatedRoute,
    private router: Router) { }

  ngOnInit(): void {
    this.listenToRouteParams();
    this.listenToRouterEvents();
  }

  private listenToRouteParams() {
    // ActivatedRoute.paramMap observable changes whenever the URL's id changes
    this.currentMovie$ = this.route.paramMap.pipe(

      // extract film id parameter
      map(params => params.get('id')),

      // switchMap because can discard in-flight request for a new id
      switchMap(id => {
        return this.filmService.getFilm(id).pipe(
          tap(movie => this.currentId = movie ? movie.id : 0)
        );
      })
    );
  }

  nextMovie() {
    this.navigate(this.currentId + 1);
  }

  previousMovie() {
    this.navigate(this.currentId - 1);
  }

  navigate(id: number) {
    id = id || 1;
    this.router.navigate([`/movie/${id}`]);
  }




  /// ROUTER EVENTS ////
  private listenToRouterEvents() {
    // Listen to the router do its thing
    // What is `routerEventsSubscription`?
    this.routerEventsSubscription = this.router.events.subscribe(event => {
      console.log('Router event: ', event);
    });
    console.log('MovieComponent initialized');
  }

  ngOnDestroy(): void {
    console.log('MovieComponent destroyed');

    // Question: Why must we unsubscribe from the router?
    // Question: Why do we NOT unsubscribe from `route.paramMap`
    this.routerEventsSubscription.unsubscribe();
  }

}

服务:

// tslint:disable:member-ordering
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

import { of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

import { Movie, RootObject } from './../sw-interfaces';
import { SwUrlService } from '../../samples/sw-url.service';

@Injectable()
export class FilmService {
    constructor(private http: HttpClient, private swUrlService: SwUrlService) {}

    getFilm(id: string) {
      return this.http.get<RootObject<Movie>>(`${this.url}/${id}`)
        .pipe(
          map(data => data.results),
          catchError(err => {
            if (err.status === 404) {
              return of(undefined); // OK if not found.
            }

            // log HTTP error and ...
            console.error('GET failed', err)
            // rethrow as a user-friendly message
            throw new Error('Sorry but can\'t get movies right now; please try ain  later');
          })
        );
    }

    private get url() {
        return this.swUrlService.url;
    }
}