Angular跨组件共享服务传值如何实时响应数据变更
Angular跨组件实时同步选中值实现方案
用RxJS的BehaviorSubject改造共享服务即可实现数据变更的实时推送,无需手动触发变更检测,具体改造步骤如下:
1. 改造根级共享服务
把原来直接存储普通对象的写法,替换为BehaviorSubject作为内部数据源,对外暴露只读的可观察流,避免组件外部随意篡改数据流:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root', }) export class SharedDataService { // 初始化传入空对象作为默认初始值 private readonly _selectedData$ = new BehaviorSubject<object>({}); // 对外暴露只读流,组件仅可订阅不可手动推送值 readonly selectedData$ = this._selectedData$.asObservable(); constructor() {} setSelectedData(data: object) { // 新值传入时调用next向所有订阅方推送更新 this._selectedData$.next(data); } }
选择
BehaviorSubject而非普通Subject的原因:它会缓存最新一次推送的值,表格组件哪怕在选项选中后才完成初始化,订阅时也能立刻拿到当前已选中的项,不会漏掉数据。
2. 按钮组件无需大幅调整
原有选中逻辑基本可以复用,仍然调用服务的setSelectedData方法传值即可,方法内部会自动完成变更推送:
onSelect(company: any) { for (var i: number = 0; i < this.items.length; i++) { if (this.items[i].id == company.target.value) { this.selectedCompany = this.items[i]; this.sharedData.setSelectedData(this.selectedCompany); } } }
3. 改造表格组件取值逻辑
删掉原来ngOnInit中单次读取服务数据的写法,改为订阅服务暴露的数据流,每次选中项更新时都会自动触发筛选逻辑。注意组件销毁时要取消订阅,避免内存泄漏:
import { Subscription } from 'rxjs'; // 组件内声明订阅实例 private dataSub!: Subscription; selectedCompany: object = {}; ngOnInit(): void { this.onGetItems(); // 订阅选中项数据流,值变更时自动执行回调 this.dataSub = this.sharedData.selectedData$.subscribe(selected => { this.selectedCompany = selected; if (Object.getOwnPropertyNames(this.selectedCompany).length === 0) { // 未选中项逻辑:比如展示全量表格数据 } else { // 拿到最新选中项,执行表格筛选、视图刷新逻辑 } }) } ngOnDestroy(): void { // 组件销毁时取消订阅,防止内存泄漏 this.dataSub?.unsubscribe(); }
更简便的优化写法
如果模板中直接使用选中值做渲染判断,可直接用async管道绑定服务暴露的数据流,Angular会自动处理订阅、取消订阅的生命周期逻辑,省去手动管理订阅的步骤:
<!-- 表格模板示例 --> <ng-container *ngIf="sharedData.selectedData$ | async as selectedCompany"> <!-- 直接使用selectedCompany做筛选判断,渲染对应表格行 --> </ng-container>
内容的提问来源于stack exchange,提问作者Clare Iron
相关产品推荐
相关产品推荐

