---
nav:
  title: 组件
  order: 1
group:
  title: Data Entry
  order: 1
title: PisellDataSourceContainer
order: 1
category: pro
---

# PisellDataSourceContainer 数据源容器

PisellDataSourceContainer 为列表页提供统一的数据管理、操作处理、状态共享与子组件协调能力，内置数据源管理、list/get/create/update/destroy 操作、RefManager 与 SharedState、以及 Filter/Table/Pagination/Sort 等子组件的 props 管理。

## 何时使用

- 列表页需要统一的数据源与查询/分页/筛选
- 多子组件（筛选、表格、分页、排序）需共享数据与操作
- 需要跨组件共享状态（如选中行、当前 Tab）而不 props 层层下传
- 基于同一套数据源的增删改查与表格联动

## 特性

- **数据源管理**：统一 dataSource 配置，支持动态切换、extraParams、overrideData
- **操作封装**：list.onSearch / onReset / onPageChange，以及 get、create、update、destroy
- **状态共享**：RefManager 的 registerRef/getRef、SharedState 的 setSharedState/subscribeSharedState
- **子组件协调**：childComponentProps 统一配置 Filter、Table、Pagination、Sort 等
- **表单集成**：内置 Form 实例，表单值变化可联动查询

## 代码演示

### 简单列表查询

```tsx
import React from 'react';
import { PisellDataSourceContainer } from '@pisell/materials';

export default () => {
  return (
    <PisellDataSourceContainer
      dataSource="users"
      autoRun={{ list: true }}
      pagination={true}
    >
      <PisellDataSourceContainer.Table />
      <PisellDataSourceContainer.Pagination />
    </PisellDataSourceContainer>
  );
};
```

### 带筛选的列表

```tsx
import React from 'react';
import { PisellDataSourceContainer } from '@pisell/materials';

export default () => {
  const childComponentProps = {
    filterComponent: {
      value: {
        quickFilter: [
          { name: 'keyword', label: '关键词', type: 'input', props: {}, other: {} },
          {
            name: 'status',
            label: '状态',
            type: 'single',
            props: {
              options: [
                { label: '全部', value: '' },
                { label: '启用', value: '1' },
                { label: '禁用', value: '0' },
              ],
            },
            other: {},
          },
        ],
      },
    },
    tableComponent: {
      columns: [
        { title: 'ID', dataIndex: 'id' },
        { title: '名称', dataIndex: 'name' },
        { title: '状态', dataIndex: 'status' },
      ],
    },
  };

  return (
    <PisellDataSourceContainer
      dataSource="products"
      autoRun={{ list: true }}
      pagination={{ pageNumber: 1, pageSize: 20 }}
      childComponentProps={childComponentProps}
    >
      <PisellDataSourceContainer.Filter />
      <PisellDataSourceContainer.Table />
      <PisellDataSourceContainer.Pagination />
    </PisellDataSourceContainer>
  );
};
```

### 自定义子组件（useContainerContext）

通过 `PisellDataSourceContainer.useContainerContext` 获取 `serverActions`、`refManager`、`form`，在自定义子组件内发起查询或读取数据。

```tsx
import React from 'react';
import { PisellDataSourceContainer } from '@pisell/materials';

const useContainerContext = PisellDataSourceContainer.useContainerContext;

const CustomList = () => {
  const { serverActions } = useContainerContext();
  const { data, loading } = serverActions.list;

  return (
    <div>
      {loading && <div>加载中...</div>}
      {data?.list?.map((item: { id: string; name: string }) => (
        <div key={item.id}>{item.name}</div>
      ))}
    </div>
  );
};

export default () => {
  return (
    <PisellDataSourceContainer dataSource="items" autoRun={{ list: true }}>
      <CustomList />
    </PisellDataSourceContainer>
  );
};
```

### 使用 withContainer 包装子组件

使用 `PisellDataSourceContainer.withContainer` 将自定义组件挂到容器的 childComponentProps 上，并注入 `serverActions`、`refManager`、`form` 等。

```tsx
import React from 'react';
import { PisellDataSourceContainer } from '@pisell/materials';

const withContainer = PisellDataSourceContainer.withContainer;

const MyTableComponent = ({
  serverActions,
  refManager,
  form,
}: {
  serverActions: any;
  refManager: any;
  form: any;
}) => {
  const { data, loading, onSearch } = serverActions.list;
  return (
    <div>
      <button onClick={() => onSearch({ keyword: 'test' })}>搜索</button>
      {loading ? '加载中' : (data?.list?.length ?? 0) + ' 条'}
    </div>
  );
};

const MyTable = withContainer(MyTableComponent, 'tableComponent');

export default () => {
  return (
    <PisellDataSourceContainer dataSource="users" autoRun={{ list: true }}>
      <MyTable />
    </PisellDataSourceContainer>
  );
};
```

### RefManager 与 SharedState

通过 `refManager.setSharedState` / `subscribeSharedState` 做跨组件状态同步；订阅需在卸载时取消。

```tsx
import React, { useEffect } from 'react';
import { PisellDataSourceContainer } from '@pisell/materials';

const useContainerContext = PisellDataSourceContainer.useContainerContext;

const ComponentA = () => {
  const { refManager } = useContainerContext();
  useEffect(() => {
    const unsubscribe = refManager.subscribeSharedState('selectedIds', (ids: string[]) => {
      console.log('选中的 IDs:', ids);
    });
    return () => unsubscribe();
  }, [refManager]);
  return <div>组件 A</div>;
};

const ComponentB = () => {
  const { refManager } = useContainerContext();
  const handleSelect = (ids: string[]) => {
    refManager.setSharedState('selectedIds', ids);
  };
  return <button onClick={() => handleSelect(['1', '2', '3'])}>选择</button>;
};

export default () => {
  return (
    <PisellDataSourceContainer dataSource="users">
      <ComponentA />
      <ComponentB />
    </PisellDataSourceContainer>
  );
};
```

### 自定义操作（导出、批量删除）

在子组件内通过 `serverActions` 与 `form` 组合实现导出、批量删除等，操作后调用 `list.onSearch()` 刷新列表。

```tsx
import React from 'react';
import { PisellDataSourceContainer } from '@pisell/materials';

const useContainerContext = PisellDataSourceContainer.useContainerContext;

const CustomActions = () => {
  const { serverActions, form } = useContainerContext();
  const { list } = serverActions;

  const handleExport = () => {
    const values = form.getFieldsValue();
    console.log('导出条件', values);
  };

  const handleBatchDelete = async () => {
    await serverActions.destroy.run({ ids: ['1', '2'] });
    list.onSearch();
  };

  return (
    <div style={{ marginBottom: 16 }}>
      <button onClick={handleExport}>导出</button>
      <button onClick={handleBatchDelete}>批量删除</button>
    </div>
  );
};

export default () => {
  return (
    <PisellDataSourceContainer dataSource="users" autoRun={{ list: true }}>
      <CustomActions />
      <PisellDataSourceContainer.Table />
      <PisellDataSourceContainer.Pagination />
    </PisellDataSourceContainer>
  );
};
```

## API

### PisellDataSourceContainer Props

| 参数                | 说明           | 类型                                                  | 默认值 | 必填 |
| ------------------- | -------------- | ----------------------------------------------------- | ------ | ---- |
| dataSource          | 数据源配置     | `string \| DataSourceConfig`                          | -      | 是   |
| children            | 子组件         | `ReactNode`                                           | -      | 是   |
| autoRun             | 自动执行配置   | `{ list?: boolean }`                                  | -      | 否   |
| pagination          | 分页配置       | `boolean \| { pageNumber: number; pageSize: number }` | `true` | 否   |
| extraParams         | 额外请求参数   | `{ list?: Record<string, any> }`                      | -      | 否   |
| actions             | 操作方法配置   | `ActionsConfig`                                       | -      | 否   |
| overrideData        | 数据覆盖       | `any`                                                 | -      | 否   |
| currentValue        | 当前值         | `any`                                                 | -      | 否   |
| __designMode        | 设计模式       | `boolean`                                             | -      | 否   |
| childComponentProps | 子组件属性配置 | `ChildComponentPropsType`                             | -      | 否   |

### ChildComponentPropsType

| 参数                    | 说明                 | 类型 |
| ----------------------- | -------------------- | ---- |
| filterComponent         | Filter 组件属性      | `{ value: { quickFilter?, otherFilter? }; formFiltersPrefix?; quickFilterMaxLength? }` |
| quickFilterComponent    | QuickFilter 组件属性 | `{ filterList; formFiltersPrefix? }` |
| filterButtonComponent   | FilterButton 组件属性| `FilterListProps` |
| tabsComponent           | Tabs 组件属性        | `{ items; type? }` |
| sortComponent           | Sort 组件属性        | `SortListProps` |
| tableComponent          | Table 组件属性       | `AntdTableProps<any>` |
| columnsSettingComponent | ColumnsSetting 组件属性 | `{ value?; onChange? }` |
| paginationComponent     | Pagination 组件属性  | `PaginationProps` |

### useContainerContext 返回值

| 参数           | 说明               | 类型 |
| -------------- | ------------------ | ---- |
| serverActions  | 服务端操作方法集合 | `HandleActionContextType` |
| refManager     | 引用管理器         | `RefManagerContextType` |
| form           | 表单实例           | `FormInstance` |
| onValuesChange | 表单值变化回调     | `(changedValues, allValues) => void` |

### serverActions.list

| 参数         | 说明                     | 类型 |
| ------------ | ------------------------ | ---- |
| data         | 列表数据                 | `{ list: any[]; count: number }` |
| loading      | 加载状态                 | `boolean` |
| error        | 错误信息                 | `Error` |
| run          | 执行查询（原始方法）     | `(params) => void` |
| onSearch     | 查询（自动处理分页）     | `(params?) => void` |
| onReset      | 重置                     | `() => void` |
| onPageChange | 分页切换                 | `(pageNumber, pageSize) => void` |
| pagination   | 当前分页状态             | `{ pageNumber; pageSize }` |

### refManager 方法

| 方法                 | 说明         | 类型 |
| -------------------- | ------------ | ---- |
| registerRef          | 注册组件引用 | `<T>(id: string, ref: T) => void` |
| getRef               | 获取组件引用 | `<T>(id: string) => T \| undefined` |
| unregisterRef        | 注销组件引用 | `(id: string) => void` |
| getSharedState       | 获取共享状态 | `<T>(key: string) => T \| undefined` |
| setSharedState       | 设置共享状态 | `<T>(key: string, value: T) => void` |
| subscribeSharedState | 订阅共享状态 | `<T>(key: string, callback: (value: T) => void) => () => void` |

## 内置子组件

| 子组件 | 说明 |
|--------|------|
| `PisellDataSourceContainer.Filter` | 筛选，支持快速筛选与高级筛选 |
| `PisellDataSourceContainer.QuickFilter` | 快速筛选 |
| `PisellDataSourceContainer.FilterButton` | 筛选按钮 |
| `PisellDataSourceContainer.Table` | 表格，自动连接数据源 |
| `PisellDataSourceContainer.Pagination` | 分页 |
| `PisellDataSourceContainer.Sort` | 排序 |
| `PisellDataSourceContainer.ColumnsSetting` | 列设置 |

## 注意事项

1. **数据源**：`dataSource` 可为字符串（表名）或完整数据源配置对象。
2. **分页**：启用 `pagination` 时，`onSearch` 会重置到第一页。
3. **表单**：容器内置 Form，子组件通过 `childComponentProps` 与 Form 联动，表单变化可触发查询。
4. **Ref**：使用 `withContainer` 包装的组件会自动注册/注销 ref。
5. **SharedState**：`subscribeSharedState` 返回取消订阅函数，请在组件卸载时调用。
6. **性能**：子组件内合理使用 `useMemo` / `useCallback` 减少重复渲染。

## 相关文档

- [设计文档](./PisellDataSourceContainer.$tab-design.md)
- [开发文档](./PisellDataSourceContainer.$tab-dev.md)
- [测试文档](./PisellDataSourceContainer.$tab-test.md)
