应用程序中出现通配符路由(未找到页面)时,不会生成应用程序外壳

问题描述 投票:0回答:1

是的,我正在努力使用 Angular 应用程序外壳,因为我的应用程序路由中有一个通配符。我的项目是一个独立的 Angular 项目。我们该如何解决这个问题?

app.config.server.ts
文件:

import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/platform-server';
import { appConfig } from './app.config';
import { ROUTES } from '@angular/router';
import { AppShellComponent } from './app-shell/app-shell.component';

const serverConfig: ApplicationConfig = {
  providers: [
    provideServerRendering(),
    {
      provide: ROUTES,
      multi: true,
      useValue: [
        {
          path: 'shell',
          component: AppShellComponent,
        },
      ],
    },
  ],
};

export const config = mergeApplicationConfig(appConfig, serverConfig);

我还经历过,如果我使用

APP_INITIALIZER
并尝试重定向到错误页面(基于我们的逻辑),App-shell 会导航到该错误页面并将该页面嵌入到我们的 HTML 中,而不是嵌入 app-shell 页面本身!怎么解决这个问题?!

app.config.ts
文件:

import { APP_INITIALIZER, ApplicationConfig, isDevMode } from '@angular/core';
import {
  Router,
  provideRouter,
  withEnabledBlockingInitialNavigation,
} from '@angular/router';
import { appRoutes } from './app.routes';

function initAppFactoryConfig(router: Router) {
  return () => new Promise((resolve, reject) => {

    // We resolve the promise whatsoever! Because we want the app to complete 
    // its initialization... BUT based on our logic (e.g., if the file we're 
    // trying to load at initialization, couldn't get loaded), we may like to 
    // redirect to one of our app's pages and then resolve... In this case 
    // app-shell embeds the error page into the HTML instead!
    router.navigate(['/error-loading']);
    resolve(true);
  });
}

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(appRoutes, withEnabledBlockingInitialNavigation()),
    {
      provide: APP_INITIALIZER,
      useFactory: initAppFactoryConfig,
      deps: [Router],
      multi: true,
    },
  ],
};
angular angular2-routing app-shell app-initializer
1个回答
0
投票

在 Angular 18 中,我通过在通配符路由中添加

canMatch
防护来解决这个问题,这样它只在客户端匹配。

import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { CanMatch, Route, UrlSegment } from '@angular/router';
import { isPlatformServer } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class ClientOnlyGuard implements CanMatch {

  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

  canMatch(route: Route, segments: UrlSegment[]): boolean {
    const isServer = isPlatformServer(this.platformId);
    return !isServer;
  }
}

然后...

{ path: '**', loadComponent: () => import('src/app/errors/not-found/not-found.component').then(x => x.NotFoundComponent), canMatch: [ClientOnlyGuard] },
© www.soinside.com 2019 - 2024. All rights reserved.