Angular 5:如何在懒加载特性模块的组件间共享同一服务实例?
解决Angular 5懒加载Feature Module内组件共享服务实例的问题
首先得明确Angular懒加载模块的核心特性:懒加载的Feature Module会拥有独立的注入器,所以只要把服务正确注册在该模块的providers数组中,整个模块内的所有组件都会共享这个服务的单一实例——这正是你想要的效果。你之前遇到的问题大概率是配置上的小疏漏,下面一步步给你梳理正确的操作:
1. 正确创建并注册服务到Feature Module
- 先在Feature Module目录下创建共享服务,比如
shared-data.service.ts:
import { Injectable } from '@angular/core'; @Injectable() export class SharedDataService { private sharedObject: any; setSharedData(data: any) { this.sharedObject = data; } getSharedData() { return this.sharedObject; } }
- 接着把这个服务添加到Feature Module的
providers数组中(别放到AppModule里了):
// 你的feature module文件,比如user.module.ts import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { ComponentA } from './component-a.component'; import { ComponentB } from './component-b.component'; import { SharedDataService } from './shared-data.service'; const routes: Routes = [ { path: 'component-a', component: ComponentA }, { path: 'component-b', component: ComponentB } ]; @NgModule({ declarations: [ComponentA, ComponentB], imports: [RouterModule.forChild(routes)], providers: [SharedDataService] // 在这里注册服务,模块内组件共享同一实例 }) export class UserModule { }
2. 在组件中注入并使用服务
- 在ComponentA中设置要传递的数据,再跳转到ComponentB:
import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { SharedDataService } from './shared-data.service'; @Component({ selector: 'app-component-a', template: ` <button (click)="passDataToComponentB()">跳转到ComponentB并传数据</button> ` }) export class ComponentA { constructor(private sharedService: SharedDataService, private router: Router) { } passDataToComponentB() { const userInfo = { id: 101, name: '张三' }; this.sharedService.setSharedData(userInfo); this.router.navigate(['/user/component-b']); // 路由要和你的懒加载配置匹配 } }
- 在ComponentB中获取传递过来的数据:
import { Component, OnInit } from '@angular/core'; import { SharedDataService } from './shared-data.service'; @Component({ selector: 'app-component-b', template: ` <div>从ComponentA收到的数据:{{ receivedData | json }}</div> ` }) export class ComponentB implements OnInit { receivedData: any; constructor(private sharedService: SharedDataService) { } ngOnInit() { this.receivedData = this.sharedService.getSharedData(); } }
3. 排查你可能踩的坑
如果把服务放在Feature Module的providers里没生效,大概率是以下原因:
- 重复注册服务:要是你在某个组件的
providers里也注册了这个服务,组件会创建自己的服务实例,直接覆盖模块级的共享实例。一定要确保只有Feature Module的providers数组里有这个服务。 - 路由配置错误:检查
AppModule里的懒加载路由是否正确,比如应该是{ path: 'user', loadChildren: './user/user.module#UserModule' },这样Feature Module的子路由才能正确挂载。 - 数据传递时机问题:如果ComponentB加载时还没拿到数据(比如路由跳转太快),可以把服务改成用
BehaviorSubject实现响应式传递,数据更新时ComponentB能自动接收:
// 修改后的SharedDataService import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @Injectable() export class SharedDataService { private dataSubject = new BehaviorSubject<any>(null); sharedData$ = this.dataSubject.asObservable(); setSharedData(data: any) { this.dataSubject.next(data); } }
然后在ComponentB中订阅数据:
ngOnInit() { this.sharedService.sharedData$.subscribe(data => { if (data) { this.receivedData = data; } }); }
按照上面的配置,懒加载Feature Module内的两个组件就能稳稳共享同一个服务实例,完美实现跨组件数据传递啦。
内容的提问来源于stack exchange,提问作者1Z10
相关产品推荐
相关产品推荐

