如果解析失败,重定向 Angular 2

28

如果在Angular 2中解析失败,我该如何重定向到另一个页面? 我调用此解析程序以进行编辑页面,但我希望在解析页面处理错误

我的解析程序:

 resolve(route: ActivatedRouteSnapshot): Promise<any>|boolean {

        return new Promise((resolve, reject) => {

            if (route.params['id'] !== undefined) {
                this.dataService.getHttpEmpresaShow(this.endpoint_url_Get + route.params['id'])
                    .subscribe(
                     result => {                    
                            console.log("ok");
                            return resolve(result);                     
                    },
                    error => {
                return resolve(error);
            });
    }});

相关的Github问题:https://github.com/angular/angular/issues/29089 - 请求与Angular 7.1中Authguards的等效功能相同。 (https://blog.ninja-squad.com/2018/11/22/what-is-new-angular-7.1/) - Simon_Weaver
2个回答

39

就像文档中所述,调用this.router.navigate(["url"])...(记得在构造函数中注入Router

class MyResolve {

  constructor(private router: Router) {}

  resolve(route: ActivatedRouteSnapshot): Observable <any> {
    return this.dataService.getHttpEmpresaShow(this.endpoint_url_Get + route.params['id'])
      .pipe(catchError(err => {
        this.router.navigate(["/404"]);
        return EMPTY;
      }));
  }
}

15
有一个 /404 路由真的不太方便!理想情况下,我们应该能够保留原始URL(例如posts/some-missing-id),并显示一个错误组件而不是原始处理程序组件。有没有办法实现这样的机制来(全局)处理解析守卫中的错误? - Alireza Mirian
3
这是一种不良的做法。我从未见过后端Web服务器重定向到专用的404网页。那么为什么在前端这样做呢? - Reactgular
3
我认为你不理解这里做了什么。如果你有一个路由器出口只用于显示单个项目,当你找不到该项目时,在同一位置显示404消息而不更改URL。那就是你所谈论的确切行为!你只需要将{skipLocationChang:true}作为选项传递给router.navigate(url,options)即可。@cgTag - n00dl3
4
@n00dl3,你自己试过了吗?skipLocationChange:true在数据解析器中似乎无效。如果你访问的URL是第一个URL,并且无法解析数据并重定向到404,则原始URL不会被保存,并且总是变为根路径"/",这时使用this.router.navigate(['404'], {skipLocationChange: true});也没有帮助。这是Angular 4的问题,不确定它是路由器的Bug还是一个特性... - Vladimir Tolstikov
1
感谢大家的讨论,特别是@VladimirTolstikov发布的网址链接:它给了我一个起点,然后我做了一些改变,最终得到了自己的解决方案,就是这样: this.router.navigate(['/page-not-found'], {replaceUrl: true}).then(() => this.location.replaceState(state.url));。基本上,我重定向到404错误页面,然后用原始URL替换地址栏中的网址,以使用户的导航流程连贯。 - AlexGpeppe
显示剩余8条评论

1
如果您想在所有解析器失败后应用重定向策略,可以拦截路由事件并在失败事件上应用重定向。这里是您可以添加到AppComponent中的代码:
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { Router, RouterEvent, NavigationError } from '@angular/router';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor(
    private router: Router,
    private cdr: ChangeDetectorRef
  ){}


  ngOnInit() {    
    this.router.events.subscribe((event: RouterEvent) => {
      this.navigationInterceptor(event)
    });
  }

  navigationInterceptor(event: RouterEvent): void {
    if (event instanceof NavigationError) {
      this.router.navigate(["error"],{ queryParams: { redirect: event.url } });
    }
    this.cdr.detectChanges();
  }

}

问题在于,如果您有嵌套的组件路由要定向到,您需要知道整个路径才能得到结果,而在原地放置redirectTo则采取您想要的路由,并在路径级别上定义。 - Captain Prinny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接