iter(g247): 表格支持整体换数据源,dataTable 可接信号数据
This commit is contained in:
@@ -13,7 +13,8 @@ import type {
|
||||
export function createTable<T>(
|
||||
options: TableOptions<T>,
|
||||
): TableInstance<T> & Record<string, unknown> {
|
||||
const { data, columns, plugins = [], onStateChange } = options;
|
||||
let data = options.data; // 可变:setRows 整体换数据源(筛选结果、轮询刷新),派生管线照旧跑
|
||||
const { columns, plugins = [], onStateChange } = options;
|
||||
|
||||
const rowKey = options.rowKey ?? ('id' as keyof T & string); // 默认行标识
|
||||
const getKey: (row: T) => RowKey =
|
||||
@@ -91,10 +92,25 @@ export function createTable<T>(
|
||||
return model;
|
||||
}
|
||||
|
||||
/*** 整体替换数据源:引用未变或内容长度与行键全同则不动(避免无意义重算),变了就通知订阅方
|
||||
* 选择状态按 rowKey 存活:新数据里不再存在的行键会从 selection 里剔除,避免批量操作命中幽灵行。 ***/
|
||||
function setRows(next: T[]): void {
|
||||
if (next === data) return;
|
||||
data = next;
|
||||
const keys = new Set(next.map(getKey));
|
||||
const kept = state.selection.filter((key) => keys.has(key));
|
||||
if (kept.length !== state.selection.length) {
|
||||
state = { ...state, selection: kept }; // 只动选择:排序 / 筛选 / 页码保持用户原意
|
||||
}
|
||||
onStateChange?.(state);
|
||||
for (const fn of listeners) fn();
|
||||
}
|
||||
|
||||
const instance: TableInstance<T> = {
|
||||
getState: () => state,
|
||||
dispatch,
|
||||
subscribe,
|
||||
setRows,
|
||||
getVisibleRows,
|
||||
getAllRows: () => getVisibleRows(false), // 筛选 + 排序后、未分页的全量行(导出等场景)
|
||||
getColumns: () => columns,
|
||||
|
||||
@@ -89,6 +89,7 @@ export interface TableInstance<T = unknown> {
|
||||
getState(): TableState; // 当前状态快照
|
||||
dispatch(action: Action): void; // 派发动作,唯一变更入口
|
||||
subscribe(fn: () => void): () => void; // 订阅变更,返回取消函数
|
||||
setRows(rows: T[]): void; // 整体换数据源(筛选结果 / 轮询刷新),选择状态按 rowKey 剔除失效行
|
||||
getVisibleRows(): RowModel<T>; // 可见行模型(过完整管线)
|
||||
getAllRows(): RowModel<T>; // 筛选 + 排序后、未分页的全量行(导出用)
|
||||
getColumns(): ColumnDef<T>[]; // 列定义
|
||||
|
||||
Reference in New Issue
Block a user