我们正在使用Angular路由器4.0.0,并且在我们的一个路由中,我们已经实现了路由器解析器服务,以便在更改路由时向组件提供数据。
然而,当使用this.router.navigate(绝对或相对,无关紧要)从job / 1 / items导航到job / 2 / items时,路由临时更改为新的(2)但然后返回旧的(1)。请注意,在解析服务中的resolve方法实现中永远不会出现错误。
我们的路由模块:
@NgModule({
imports: [
RouterModule.forChild([
{ path: "", redirectTo: "all", pathMatch:"full"},
{
path: "all",
canActivate: [AuthGuard],
component: JobsListComponent,
data: { title: 'jobs', listId: 'all', listTitle: 'AllJobs' }
},
{
path: ':id',
canActivate: [AuthGuard],
component: JobDetailComponent,
resolve: { detailData: JobDetailResolve },
children: [
{ path: '', redirectTo: 'feed', pathMatch: 'full' },
{ path: 'feed', component: JobDetailFeedComponent, data: { title: 'feed', isDetail: true } },
{ path: 'items', component: JobDetailItemsComponent, data: { title: 'items', isDetail: true } },
]
},
])
],
exports: [
RouterModule
],
providers: [
JobDetailResolve
]
})
export class JobsRoutingModule { }
我们的解决服务:
@Injectable()
export class JobDetailResolve implements Resolve<JobWithMetadata> {
constructor(private jobsService: JobsService,
private router: Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<JobWithMetadata> {
return Observable.create(observer => {
var jobId = route.params["id"];
this.jobsService.getJob(jobId).subscribe(
detailData => {
var data = new JobWithMetadata(detailData.Job, detailData.JobMetadata, detailData.Job.Number);
observer.next(data);
observer.complete();
}, error => {
error.subscribe(data => {
this.router.navigate([AppRoutes.Home,AppRoutes.Jobs]);
observer.next(null);
observer.complete();
});
});
});
}
}
最后,在单击子组件内部的链接时,使用组件内部的代码,输入goToJob2 :( click)=&#34; goToJob2()&#34;
在JobDetailItemsComponent内部,我们有上述方法:
ngOnInit() {
this.route.data
.subscribe((data: { detailData: JobWithMetadata }) => {
this.job = data.detailData.Job;
this.initComponent(); // refreshes the component data
});
}
goToJob2() {
this.router.navigate([AppRoutes.Home, AppRoutes.Jobs, "2", "items"]);
}
路由第一个更改为jobs / 2 / items但不知何故它返回到jobs / 1 / items。
对此有何建议?
由于
答案 0 :(得分:0)
在您的解析器代码中,您无需订阅错误。
@Injectable()
export class JobDetailResolve implements Resolve<JobWithMetadata> {
constructor(private jobsService: JobsService,
private router: Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<JobWithMetadata> {
return Observable.create(observer => {
var jobId = route.params["id"];
this.jobsService.getJob(jobId).subscribe(
detailData => {
var data = new JobWithMetadata(detailData.Job, detailData.JobMetadata, detailData.Job.Number);
observer.next(data);
observer.complete();
}, error => {
error.subscribe(data => {
this.router.navigate([AppRoutes.Home,AppRoutes.Jobs]);
observer.next(null);
observer.complete();
});
});
});
}
}
将代码重新格式化为
@Injectable()
export class JobDetailResolve implements Resolve<JobWithMetadata> {
constructor(private jobsService: JobsService,
private router: Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<JobWithMetadata> {
return Observable.create(observer => {
var jobId = route.params["id"];
this.jobsService.getJob(jobId).subscribe(
detailData => {
var data = new JobWithMetadata(detailData.Job, detailData.JobMetadata, detailData.Job.Number);
observer.next(data);
}, (error) => {
if(error) {
this.router.navigate([AppRoutes.Home,AppRoutes.Jobs]);
observer.next(null);
observer.complete();
}, () => {
observer.complete();
});
});
}
}
如果JobService使用HttpClient来获取数据,则默认情况下会提供Promise / Observable,因此您可以按上述方式进行订阅。当您订阅错误时,没有可观察到的错误,该错误来自http可观察到的本身。希望这会有所帮助。
如果您的服务是http通话,那么您也不需要可观察的东西。相反,您可以这样做
@Injectable()
export class JobDetailResolve implements Resolve<any> {
constructor(private service: Service) {}
resolve(route: ActivatedRouteSnapshot) {
return this.service.getJob(route.params["id"]).catch(() => {
// Navigate here
});
}
}
由于observable是一个可保证的承诺,它将自动将数据发送到您的路线解析器
{
path: ':id',
canActivate: [AuthGuard],
component: JobDetailComponent,
resolve: { detailData: JobDetailResolve },
children: [
{ path: '', redirectTo: 'feed', pathMatch: 'full' },
{ path: 'feed', component: JobDetailFeedComponent, data: { title: 'feed', isDetail: true } },
{ path: 'items', component: JobDetailItemsComponent, data: { title: 'items', isDetail: true } },
]
}