You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义Angular Router Reuse Strategy类中注入服务跟踪已分离组件?

解决方案

在Angular中,自定义RouteReuseStrategy类确实无法直接通过构造函数注入依赖(因为它由框架实例化),但可以通过以下两种方式注入你的组件跟踪服务:

方式一:使用Angular inject函数(Angular 14+)

这是最简洁的方案,利用Angular 14引入的inject函数可以直接在类属性中获取服务实例,无需构造函数处理:

1. 先创建组件跟踪服务

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class ComponentTrackingService {
  // 存储已分离的组件实例
  detachedComponents: any[] = [];

  // 添加跟踪逻辑
  trackDetachedComponent(componentInstance: any) {
    this.detachedComponents.push(componentInstance);
    // 可添加去重、日志等额外逻辑
  }

  // 其他所需方法,比如获取所有分离组件、清除列表等
}

2. 自定义路由复用策略类

import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
import { inject } from '@angular/core';
import { ComponentTrackingService } from './component-tracking.service';

export class CustomRouteReuseStrategy implements RouteReuseStrategy {
  // 直接用inject获取服务实例
  private trackingService = inject(ComponentTrackingService);
  // 用于存储路由句柄的缓存
  private routeCache = new Map<string, DetachedRouteHandle>();

  // 实现RouteReuseStrategy的必要方法
  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig;
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return this.routeCache.has(route.routeConfig?.path || '');
  }

  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
    return this.routeCache.get(route.routeConfig?.path || '') || null;
  }

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    // 根据你的需求决定是否缓存路由,这里示例为所有路由都缓存
    return !!route.routeConfig?.path;
  }

  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    const path = route.routeConfig?.path || '';
    this.routeCache.set(path, handle);
  }

  // 关键:在detach方法中跟踪分离的组件
  detach(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
    const handle = this.routeCache.get(route.routeConfig?.path || '');
    if (handle) {
      // 获取组件实例并传给跟踪服务
      this.trackingService.trackDetachedComponent(handle.componentRef.instance);
      // 可选:如果不需要保留缓存,可以移除
      // this.routeCache.delete(route.routeConfig?.path || '');
    }
    return handle || null;
  }
}

3. 在模块中注册自定义策略

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { CustomRouteReuseStrategy } from './custom-route-reuse.strategy';
import { AppComponent } from './app.component';

@NgModule({
  imports: [BrowserModule, /* 你的路由模块等 */],
  declarations: [AppComponent],
  providers: [
    { provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

方式二:使用静态Injector引用(兼容低版本Angular)

如果你的项目版本低于Angular 14,可以通过静态保存Injector实例的方式获取服务:

1. 修改自定义路由复用策略类

import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
import { Injector } from '@angular/core';
import { ComponentTrackingService } from './component-tracking.service';

export class CustomRouteReuseStrategy implements RouteReuseStrategy {
  private static injector: Injector;
  private trackingService: ComponentTrackingService;
  private routeCache = new Map<string, DetachedRouteHandle>();

  // 静态方法用于设置Injector
  static setInjector(injector: Injector) {
    CustomRouteReuseStrategy.injector = injector;
  }

  constructor() {
    // 通过Injector获取服务实例
    this.trackingService = CustomRouteReuseStrategy.injector.get(ComponentTrackingService);
  }

  // 其余RouteReuseStrategy方法实现同方式一,detach方法逻辑一致
}

2. 在AppModule中初始化Injector

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { CustomRouteReuseStrategy } from './custom-route-reuse.strategy';
import { Injector } from '@angular/core';
import { AppComponent } from './app.component';

@NgModule({
  imports: [BrowserModule, /* 你的路由模块等 */],
  declarations: [AppComponent],
  providers: [
    { provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor(injector: Injector) {
    // 初始化静态Injector
    CustomRouteReuseStrategy.setInjector(injector);
  }
}

关键说明

  • 在detach方法中,我们从DetachedRouteHandle的componentRef.instance获取到组件实例,这是跟踪分离组件的核心入口。
  • 你可以根据业务需求调整shouldDetach方法的逻辑,决定哪些路由的组件需要被跟踪。

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:32:44