在 Angular 18 中,预加载策略的注册方式采用了更简洁的 函数式配置(Functional Configuration) ,通过 withPreloading 方法来实现。以下是完整用法和原理说明:
正确注册方式(Angular 18+)
在应用的路由配置中,使用 withPreloading 函数直接注册你的自定义预加载策略:
// app.config.ts (或 app-routing.module.ts)
import { provideRouter, withPreloading } from '@angular/router';
import { SelectivePreloadingStrategyService } from './selective-preloading-strategy.service';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(
routes, // 你的路由配置数组
withPreloading(SelectivePreloadingStrategyService) // ⭐ 注册预加载策略
)
]
};
关键点解析
1. withPreloading 的作用
- 这是 Angular 18 引入的 路由配置辅助函数,用于启用预加载策略。
- 它接受一个 实现了
PreloadingStrategy接口的类(而非实例),Angular 会通过依赖注入自动实例化。
2. 为什么不需要手动实例化?
- Angular 的依赖注入系统会自动处理类的实例化。
- 如果策略服务需要其他依赖(如
HttpClient),需确保它们已在全局或模块级注入。
完整代码示例
1. 自定义预加载策略
// selective-preloading-strategy.service.ts
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';
@Injectable({ providedIn: 'root' }) // ⚠️ 必须标记为可注入服务
export class SelectivePreloadingStrategyService implements PreloadingStrategy {
preloadedModules: string[] = [];
preload(route: Route, load: () => Observable<any>): Observable<any> {
if (route.data?.['preload'] && route.path) {
this.preloadedModules.push(route.path);
return load();
}
return of(null);
}
}
2. 路由配置
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter, withPreloading } from '@angular/router';
import { routes } from './app/routes';
import { SelectivePreloadingStrategyService } from './selective-preloading-strategy.service';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(
routes,
withPreloading(SelectivePreloadingStrategyService) // ⭐ 启用自定义策略
)
]
};
新旧版本对比
| Angular <18 | Angular 18+ |
|---|---|
在模块的 providers 中注册策略服务 | 使用 withPreloading() 函数式配置 |
需要手动指定 PreloadingStrategy 令牌 | 自动关联接口,无需令牌 |
| 适合传统模块化架构 | 更适合独立组件(Standalone Components)架构 |
常见问题排查
| 问题 | 解决方案 |
|---|---|
控制台报错 No provider for PreloadingStrategy | 检查是否遗漏 withPreloading() 或 providedIn: 'root' |
| 预加载未生效 | 确保路由配置中添加了 data: { preload: true } |
| 策略服务依赖未注入 | 在服务构造函数中注入的依赖需全局可用 |
验证预加载效果
在浏览器的 Network 面板 中观察模块加载时机:
- 初始加载时,仅加载首屏必要模块(如
main.js) - 稍后自动加载标记为
preload: true的模块(如dashboard.js)