我有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;
});
答案 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;
}
}