我已经使用 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)
中提供我的路线。
我想使用我的自定义类而不是默认路由类
有人有想法吗?
谢谢
如果您只想拥有一个为您存储类别的服务,则无需扩展 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],
},
无需扩展路由器即可获得相同的效果 - 我没有看到任何缺点。您只需要确保