使用Angular 2中的Resolve在子路径之间导航返回到第一个孩子

时间:2017-06-22 09:47:58

标签: angular angular2-routing

我们正在使用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。

对此有何建议?

由于

1 个答案:

答案 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 } },

                ]
            }