Angular mat-sidenav中非父子组件如何传递数组数据
非父子组件共享复选框选中状态实现方案
跨无直接父子关系的组件传递选中数据,直接使用Angular单例服务搭配RxJS响应式流是标准实现,不需要做事件透传、路由参数传值这类维护成本高的操作,按以下三步配置即可:
- 第一步:创建状态共享服务
服务以单例形式存在,全应用内注入的同一份服务实例会持有最新的选中数据,通过响应式流把数据变更推送给所有订阅的组件。
// selected-data.service.ts import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; // 替换成你自己项目里列表项的类型定义 import { DataListItem } from 'src/app/types/data'; @Injectable({ providedIn: 'root' }) export class SelectedDataService { // 私有数据流,初始值为空选中数组 private readonly _selectedItems = new BehaviorSubject<DataListItem[]>([]); // 对外暴露只读流,避免外部组件直接篡改流状态 public readonly selectedItems$ = this._selectedItems.asObservable(); /** * 更新选中项列表 * @param items 最新的选中对象数组 */ updateSelectedItems(items: DataListItem[]) { this._selectedItems.next(structuredClone(items)); } /** * 清空所有选中项 */ clearSelected() { this._selectedItems.next([]); } }
注意不要在任何模块的providers数组里重复注册这个服务,
providedIn: 'root'会保证服务是全局单例,重复注册会生成多实例导致数据不通。
- 第二步:列表组件中注入服务,同步选中状态
你已经维护了存储选中对象的数组,只需要在复选框选中状态变化、数组更新完成后,调用服务的更新方法同步最新值即可。
// data-list.component.ts import { Component } from '@angular/core'; import { SelectedDataService } from 'src/app/services/selected-data.service'; import { DataListItem } from 'src/app/types/data'; @Component({ selector: 'app-data-list', templateUrl: './data-list.component.html' }) export class DataListComponent { // 你原本用来存选中对象的数组 selectedRecords: DataListItem[] = []; constructor(private selectedDataService: SelectedDataService) {} // 你原本绑定的复选框变更回调 onCheckChange() { // 保留你原本处理selectedRecords增删的逻辑 // 数组更新完成后同步到服务 this.selectedDataService.updateSelectedItems(this.selectedRecords); } }
- 第三步:右侧侧边栏组件注入服务,订阅选中数据
组件初始化时订阅服务暴露的选中数据流,数据变更时会自动触发更新,记得在组件销毁时取消订阅避免内存泄漏。
// right-sidenav.component.ts import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subject, takeUntil } from 'rxjs'; import { SelectedDataService } from 'src/app/services/selected-data.service'; import { DataListItem } from 'src/app/types/data'; @Component({ selector: 'app-right-sidenav', templateUrl: './right-sidenav.component.html' }) export class RightSidenavComponent implements OnInit, OnDestroy { currentSelected: DataListItem[] = []; private readonly destroy$ = new Subject<void>(); constructor(private selectedDataService: SelectedDataService) {} ngOnInit() { this.selectedDataService.selectedItems$ .pipe(takeUntil(this.destroy$)) .subscribe(latestItems => { this.currentSelected = latestItems; // 此处直接写你需要的选中属性展示逻辑即可 }); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } }
- 后续如果要加单个移除选中项、批量选中等功能,只需要在服务里新增对应修改内部数据流的方法即可,所有订阅流的组件会自动同步最新状态,不需要额外写跨组件通信逻辑。
- 不要用localStorage、sessionStorage存这类状态,这类存储不是响应式的,数据变更后侧边栏无法自动刷新,还需要额外写监听逻辑,多此一举。
内容的提问来源于stack exchange,提问作者rbrtj
相关产品推荐
相关产品推荐

