Angular 11中如何让ScopedAddressDS服务随页面导航重建?
解决方案
要实现ScopedAddressDS随页面导航重建实例,核心是缩小服务的作用域到组件级别——Angular 11中模块级服务是单例(模块未销毁则服务始终存在),而组件级服务会随组件的创建/销毁同步重建。具体操作如下:
步骤1:移除模块中的服务注册
打开ItemsDetailsModule,从providers数组中删除ScopedAddressDS:
@NgModule({ imports: [ RouterModule.forChild(routes), // others... ], declarations: [ ItemDetailsComponent, // others... ], providers: [ // 移除ScopedAddressDS // others... ], }) export class ItemsDetailsModule {}
步骤2:将服务注册到组件的providers中
修改ItemDetailsComponent的装饰器,把ScopedAddressDS加入组件自身的providers数组:
@Component({ selector: 'item-details', templateUrl: './item-details.component.html', styleUrls: ['./item-details.component.scss'], providers: [BreadcrumbsService, ScopedAddressDS], // 新增ScopedAddressDS }) export class ItemDetailsComponent implements OnInit, OnDestroy { constructor( private scopedAddressDS: ScopedAddressDS // etc... ) { } }
原理说明
- 当用户导航到
ItemDetailsComponent对应的路由时,Angular会创建该组件的新实例,同时为组件providers数组中的服务生成全新实例; - 导航离开时,组件被销毁,对应的
ScopedAddressDS实例也会被回收,内部的addressCache缓存自然清空; - 下次再进入该页面时,组件和服务实例会重新创建,确保每次使用的都是全新缓存,不会出现过期数据。
备选方案(多组件共享路由级实例场景)
如果有多个组件需要共享同一个ScopedAddressDS实例,但要求随路由重建,可以创建路由容器组件:
- 新建一个空的容器组件(比如
ItemDetailsContainerComponent); - 在容器组件的
providers中注册ScopedAddressDS; - 修改路由配置,让路由指向容器组件,容器内部通过
<router-outlet>加载原ItemDetailsComponent及其他相关组件; - 所有子组件会共享容器组件的
ScopedAddressDS实例,且容器组件随路由导航重建,服务实例也会同步更新。
内容的提问来源于stack exchange,提问作者void.pointer
相关产品推荐
相关产品推荐

