使用 Angular 17 的自定义路由类

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

我已经使用 Angular 17 一段时间了,但路由系统发生了很大变化。我想添加一个从 @angular/router 扩展的自定义类。

import {
  Event,
  EventType,
  Router,
  RouterEvent,
} from "@angular/router";
import { filter } from "rxjs";

type Category = "application" | "login" | "settings";
const pageRegexp = /^\/app\/(map|settings|operation)(?:\/|$)/;

export class CustomRouter extends Router {
  private category: { previous: Category | null; current: Category | null } = {
    previous: null,
    current: null,
  };

  constructor() {
    super();

    this.events
      .pipe(filter((event) => event.type === EventType.NavigationEnd))
      .subscribe(this.handleCategoryChange);
  }

  private handleCategoryChange(event: Event) {
    const url = (event as RouterEvent).urlAfterRedirects;
    const match = pageRegexp.exec(url);
    const currentCategory = match ? (match[1] as Category) : null;

    if (currentCategory) {
      this.category.previous = this.category.current;
      this.category.current = currentCategory;
    }
  }

  public getCategory() {
    return this.category
  }
}

我使用

app.config.ts
provideRouter(routes)
中提供我的路线。

我想使用我的自定义类而不是默认路由类

有人有想法吗?

谢谢

angular
1个回答
0
投票

如果您只想拥有一个为您存储类别的服务,则无需扩展 Router。我什至会说这是个坏主意,因为即使您正确扩展它,如果路由器中发生某些变化,您也很容易出错。

如果你还想这样做,你可以添加 Injectable 装饰器,然后就可以了。

@Injectable({providedIn: 'root'})    
export class CustomRouter extends Router { 

您现在可以将其注入到您的组件和服务中。

但是您无需实际扩展路由器即可获得相同的结果。您需要做的就是将路由器注入您的类,如下所示:

export class CustomRouter {
  private category: { previous: Category | null; current: Category | null } = {
    previous: null,
    current: null,
  };

  constructor(private router: Router) {
  }
  
  public init() {
    this.router.events
      .pipe(filter((event) => event.type === EventType.NavigationEnd))
      .subscribe(this.handleCategoryChange);
  }

  private handleCategoryChange(event: Event) {
    const url = (event as RouterEvent).urlAfterRedirects;
    const match = pageRegexp.exec(url);
    const currentCategory = match ? (match[1] as Category) : null;

    if (currentCategory) {
      this.category.previous = this.category.current;
      this.category.current = currentCategory;
    }
  }

  public getCategory() {
    return this.category
  }
}

并且只需确保在应用程序启动时的某个位置运行 init() 方法即可。您可以使用 APP_INITIALIZER 来实现 - https://angular.io/api/core/APP_INITIALIZER

将类似的内容添加到您的 app.module 或 bootstrapApplication 中:

{
  provide: APP_INITIALIZER,
  useFactory: (customRouter: CustomRouter) => { customRouter.init(); },
  multi: true,
  deps: [CustomRouter],
},

无需扩展路由器即可获得相同的效果 - 我没有看到任何缺点。您只需要确保

© www.soinside.com 2019 - 2024. All rights reserved.