Angular 4 - 没有开始斜线的 routerLinks 在未捕获的错误后被重写 [英] Angular 4 - routerLinks without starting slash get rewritten after uncaught error

查看:17
本文介绍了Angular 4 - 没有开始斜线的 routerLinks 在未捕获的错误后被重写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对 Angular 4 + zonejs:路由在未捕获错误后停止工作的跟进因为我们很难将建议的更改集成到我们的项目中.

This is a follow up to Angular 4 + zonejs: routing stops working after uncaught error since we had a hard time integration the suggested changes into our project.

这个原因可以在这个改编的plunker中看到https://embed.plnkr.co/oUE71KJEk0f1emUuMBp8/ 在 app.html 中:

The reason for this can be seen in this adapted plunker https://embed.plnkr.co/oUE71KJEk0f1emUuMBp8/ in app.html:

我们项目中的路由器链接没有以斜杠/"为前缀.一旦您在访问错误组件"后导航到另一个部分,这会破坏整个导航.所有链接都用当前路径重写,例如家.

The routerLinks in our project were not prefixed with a slash "/". This breaks the whole navigation once you navigate to another section after visiting the "Error Component". All links are being rewritten with the current path, e.g. home.

在 routerLink 属性中添加斜杠可修复此行为.

Adding the slash in the routerLink attributes fixes this behaviour.

这是为什么?

是否有一些关于此的文档/规范?

我们只找到了这个 angular 票用于RouterLink-directive的api,它说

We only found this angular ticket and the api for RouterLink-directive which says

或者不以斜线开头,路由器将查看当前激活路由的子节点.

or doesn't begin with a slash, the router will instead look in the children of the current activated route.

但这与上一个问题中建议的解决方法分别与未捕获错误发生的情况有何关系?

But how is this related to what is happening with an uncaught error respectively with the suggested workaround from the previous question?

推荐答案

发生导航错误后路由状态恢复

After an navigation error happens the routing state is restored

this.currentRouterState = storedState;
this.currentUrlTree = storedUrl;

https:///github.com/angular/angular/blob/4.1.2/packages/router/src/router.ts#L750-L751

之后在执行 createUrlTree 后,得到 startPosition:

After that within executing createUrlTree the startPosition is obtained:

function findStartingPosition(nav, tree, route) {
    if (nav.isAbsolute) { // it will be executed when you use `/` in routeLink
        return new Position(tree.root, true, 0);
    }
    if (route.snapshot._lastPathIndex === -1) { // without '/'
        return new Position(route.snapshot._urlSegment, true, 0);
    }
    ...
}

正如我们在上面的代码中看到的,当您在 routeLinks 中使用斜杠时,路由器将根据未更改的 tree.root 创建位置.

As we can see in code above when you use slash in routeLinks then router will create position based on tree.root which has not changed.

然后用于创建UrlTree(下面代码中的oldSegmentGroup)

then it is used for creating UrlTree (oldSegmentGroup in code below)

function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
    ...
    if (urlTree.root === oldSegmentGroup) { // will be false after the error
        return new UrlTree(newSegmentGroup, qp, fragment);
    }
    return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment);
}

因此解决方法可能如下:

So workaround might be as follows:

我们不再需要RouteReuseStrategy.

我们存储错误状态

let erroredUrlTree;
let erroredState;

export class AppModule {
  constructor(private router: Router) {
    router.events.subscribe(function (e) {
      if(e instanceof  NavigationError ) {
        erroredState = (router as any).currentRouterState;
        erroredUrlTree =  (router as any).currentUrlTree;
      }
    });
  }
}

并在发生错误后恢复:

@Injectable()
export class MyErrorHandler implements ErrorHandler {
  constructor(private inj: Injector) {}

  handleError(error: any): void {
    console.log('MyErrorHandler: ' + error);
    if(erroredUrlTree) {
      let router: any = this.inj.get(Router);
      router.currentRouterState = erroredState;
      router.currentUrlTree = erroredUrlTree;
      erroredState = null;
      erroredUrlTree = null;
    }
  }
}

修改后的Plunker

看起来很糟糕,但也许有助于了解问题所在

It looks terrible but maybe it will help to understand what the problem is

这篇关于Angular 4 - 没有开始斜线的 routerLinks 在未捕获的错误后被重写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆