Angular16独立应用:如何仅为特定组件注入RouteReuseStrategy
组件级自定义RouteReuseStrategy实现(Angular 16独立应用)
需求背景
在Angular 16独立应用中,需要实现自定义RouteReuseStrategy并仅将其应用于特定组件,且不依赖额外工具库。
已实现的AlwaysReloadRouteStrategy
@Injectable({ providedIn: 'root' }) export class AlwaysReloadRouteStrategy implements RouteReuseStrategy { retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null { return null; // 不复用任何路由 } shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; // 不附加已存储的路由,强制重载 } shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; // 从不分离路由,强制重载 } shouldReuseRoute( future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot ): boolean { return false; // 不复用任何路由,总是重载 } store( route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null ): void { // 不存储任何路由 } }
遇到的问题
- 组件级注入不生效:直接在组件的
providers中注入自定义策略时,调用router.navigate([this.router.url], { onSameUrlNavigation: 'reload' })无法触发重载:
@Component({ selector: 'app-configuration-general', standalone: true, imports: [ CommonModule, RouterLink, ReactiveFormsModule, ], providers: [ { provide: RouteReuseStrategy, useClass: AlwaysReloadRouteStrategy } ], templateUrl: './configuration-general.component.html' }) export class ConfigurationGeneralComponent implements OnInit, OnDestroy { constructor( private readonly router: Router, private readonly fb: FormBuilder ) {} onClick(): void { this.router.navigate([this.router.url], { onSameUrlNavigation: 'reload'}); // 无效果 } }
- 全局注入有效但不符合需求:在
main.ts的全局providers中配置该策略时功能正常,但会影响所有组件,不符合“仅应用于特定组件”的需求:
bootstrapApplication(AppComponent, { providers: [ ... provideRouter(ROUTES, withPreloading(PreloadAllModules)), { provide: RouteReuseStrategy, useClass: AlwaysReloadRouteStrategy }, ] })
- 直接赋值可行但不够规范:在组件
ngOnInit中直接为router.routeReuseStrategy赋值能生效,但希望采用更符合依赖注入规范的实现方式:
ngOnInit(): void { this.router.routeReuseStrategy = new AlwaysReloadRouteStrategy(); }
规范的组件级注入解决方案
由于Router实例是根注入器提供的全局实例,它初始化时依赖的RouteReuseStrategy来自根注入器,组件级注入的策略不会自动被Router使用。我们可以通过以下方式实现组件级的策略应用:
- 在组件中注入组件级的
RouteReuseStrategy和原始的根级策略 - 在组件初始化时替换
Router的策略 - 在组件销毁时恢复原始策略,避免影响其他组件
修改后的组件代码:
@Component({ selector: 'app-configuration-general', standalone: true, imports: [ CommonModule, RouterLink, ReactiveFormsModule, ], providers: [ { provide: RouteReuseStrategy, useClass: AlwaysReloadRouteStrategy } ], templateUrl: './configuration-general.component.html' }) export class ConfigurationGeneralComponent implements OnInit, OnDestroy { // 保存根注入器提供的原始策略 private originalRouteReuseStrategy: RouteReuseStrategy; constructor( private readonly router: Router, private readonly fb: FormBuilder, // 注入组件级的自定义策略 @Inject(RouteReuseStrategy) private customRouteReuseStrategy: RouteReuseStrategy ) { // 获取根级的原始策略 this.originalRouteReuseStrategy = router.routeReuseStrategy; } ngOnInit(): void { // 替换为组件级自定义策略 this.router.routeReuseStrategy = this.customRouteReuseStrategy; } ngOnDestroy(): void { // 销毁时恢复原始策略 this.router.routeReuseStrategy = this.originalRouteReuseStrategy; } onClick(): void { this.router.navigate([this.router.url], { onSameUrlNavigation: 'reload'}); // 正常生效 } }
方案说明
- 通过组件级
providers注入自定义策略,符合依赖注入的规范,避免直接实例化类 - 在组件生命周期内替换
Router的策略,仅对当前组件生效 - 组件销毁时恢复原始策略,确保其他组件不受影响
内容的提问来源于stack exchange,提问作者Andrei Manolache
相关产品推荐
相关产品推荐

