网站搜索

typescript - 在捕获错误时显示错误页面(不重定向) angular 2+


我有一个包含文章的博客。当我在博客页面的特定文章上(URL 为 /blog/article-title)时,我会显示一个加载动画并发出 GET 请求,当请求成功时,我会显示与该文章相关的信息。但如果我直接在 URL 中输入,例如 /blog/123(我没有这篇文章),我会看到加载动画并在控制台出现错误。我想要的是显示错误页面,但显示的是不正确的 URL(blog/123)。我该如何做到这一点?

应用路由模块

const routes: Routes = [
    {
        path: '',
        loadChildren: () => import('./main-page/main-page.module').then(m => m.MainPageModule),
    },
    {
        path: 'blog',
        loadChildren: () => import('./blog-page/blog-page.module').then(m => m.BlogPageModule),
    },
    {
        path: '**',
        loadChildren: () => import('./error-page/error-page.module').then(m => m.ErrorPageModule),
    },
];

博客页面路由模块

export const routes: Route[] = [
    {
        path: '',
        component: BlogPageComponent,
        children: [
            {
                path: '',
                component: ArticlesPageComponent,
            },
            {
                path: ':id',
                component: ArticlePageComponent,
            },
        ],
    },
];

文章页面

public ngAfterViewInit(): void {
        if (!this.article) {
            this.articleSubscription = this.route.paramMap
                .pipe(
                    switchMap(params => {
                        this.isLoadingInProgress = true;
                        return this.dataService.getArticleById(params.get('id'));
                    }),
                )
                .subscribe(response => {
                        this.article = response.currentArticle;
                        this.prevArticle = response.prevArticle;
                        this.nextArticle = response.nextArticle;
                        this.navigationModel = {
                            prevItem: {
                                route: this.prevArticle ? `blog/${this.prevArticle.id}` : null,
                                text: this.prevArticle && this.prevArticle.title,
                                image: this.prevArticle && this.prevArticle.mainImageUrl,
                            },
                            nextItem: {
                                route: this.nextArticle ? `blog/${this.nextArticle.id}` : null,
                                text: this.nextArticle && this.nextArticle.title,
                                image: this.nextArticle && this.nextArticle.mainImageUrl,
                            },
                        };
                        this.isLoadingInProgress = false;
                        this.changeDetection.markForCheck();
                    },
                    error => {
                        this.isLoadingInProgress = false;
                    });
        }
    }

已更新:当 URL 不正确时会显示错误页面(localhost:4200/123),但在博客 URL(localhost:4200/blog/123)下不起作用

答案#1

一个简单的解决方法是在你的组件中添加一个 error 字段:

error = false;
public ngAfterViewInit(): void {
        if (!this.article) {
            this.articleSubscription = this.route.paramMap
                .pipe(
                    ...
                )
                .subscribe(response => {
                        ...
                        this.isLoadingInProgress = false;
                        this.changeDetection.markForCheck();
                    },
                    error => {
                        this.error = true;
                        this.isLoadingInProgress = false;
                    });
        }
    }

并在模板中使用error

<div *ngIf="error; else content"><app-error>...</app-error></div>
<ng-template #content>
  ...
</ng-template>

如果你不想每次都写相同的样板代码,你可以考虑一个通知系统或覆盖/警告消息

答案#2

是的,它按预期工作,因为 localhost:4200/blog/123 不是无效的 URL,路由会捕获无效 URL。但当你在 article-page 中到达 ngAfterViewInit 时,这意味着它绝对是一个有效的路由。

解决方案是在视图内部处理无效的动态 ID,这可以通过不同的方式来实现:

  • 重定向到错误页面。
  • 警报/弹出消息
  • 创建内联错误页面,并按如下方式使用,比 *ngIf 更好,以避免从 DOM 中创建/移除:

<div [hidden]="!showError">
  <h1>Error Message</h1>
</div>  

<div [hidden]="showError">   
/ /Articles
</div>