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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:33:11