TinyBase Solid 组件实战:用 EditableCellView 让表格单元格在浏览器中直接可编辑

发布时间:2026/10/13 2:06:14
TinyBase Solid 组件实战:用 EditableCellView 让表格单元格在浏览器中直接可编辑
数据库后端前端【免费下载链接】tinybaseA reactive data store sync engine.项目地址https://gitcode.com/gh_mirrors/ti/tinybase点击查看免费下载本文是 TinyBase「UI Components (Solid)」系列演示的组成部分围绕ui-solid-dom模块中的EditableCellView组件展开它能在浏览器环境下把一个 Store 中指定 Table 的某个 Cell 渲染成可编辑控件并支持内联切换值类型string / number / boolean / object / array。读完本文你将掌握该组件的最小化用法、如何基于 TableInHtmlTable 演示快速改造出可编辑表格、如何通过editable属性让整张表进入可编辑模式以及它背后的类型切换与校验实现原理。背景ui-solid-dom 模块与组件定位TinyBase 的ui-solid-dom模块提供一组面向浏览器的响应式 HTML 表格组件用来以声明式方式渲染 Store 中的数据。其中既有纯展示组件ValuesInHtmlTable、TableInHtmlTable、SortedTableInHtmlTable、SliceInHtmlTable、RelationshipInHtmlTable、ResultTableInHtmlTable、ResultSortedTableInHtmlTable也有一对可编辑组件组件作用EditableCellView渲染一个 Cell并允许修改它的值和类型EditableValueView渲染一个 Value并允许修改它的值和类型正如 Using Solid DOM Components 指南 所说明的ui-solid-dom是纯客户端模块其包导出仅在browser条件下可用组件不支持服务端渲染SSR。Styling 与 class 命名刻意保持基础需要你用自己的 CSS 去贴合应用的视觉风格。本演示09_EditableCellView.md没有从零搭建脚手架而是在 TableInHtmlTable (Solid) 演示 的基础上做增量改造这也是该系列一贯的递进式写法——先有表再让表里的单元格变得可编辑。第一步导入组件在 TableInHtmlTable 演示 的工程里原本从tinybase/ui-solid-dom只导入了TableInHtmlTable。现在把EditableCellView一并导入-import {TableInHtmlTable} from tinybase/ui-solid-dom; import {EditableCellView, TableInHtmlTable} from tinybase/ui-solid-dom;完成这步后工程里就同时拥有了表格渲染组件与单元格编辑组件。第二步最小化用法——定位一个 CellEditableCellView的使用非常简单只需提供tableId、rowId、cellId三个属性组件就会读取对应 Cell 的值并渲染出可编辑控件。对应到类型定义它接收的是 CellProps外加可选的className与showType而CellProps正是由tableId、rowId、cellId三个必填 Id 与可选的store组成export type CellProps { readonly tableId: Id; readonly rowId: Id; readonly cellId: Id; readonly store?: StoreOrStoreId; readonly debugIds?: boolean; };原演示用TableInHtmlTable渲染了两份genres表一份去掉表头与 Id 列一份传入customCells。现在用独立的编辑面板替换它们专门编辑genres表中行g05的name单元格- TableInHtmlTable tableIdgenres headerRow{false} idColumn{false} / - TableInHtmlTable tableIdgenres customCells{customCells} / div idedit Genre 5 name: EditableCellView tableIdgenres rowIdg05 cellIdname / /div / ); };为什么是g05演示使用了一个只有 16 行、两列Id 与 name的电影类型小表。对照仓库中的示例数据 docs/assets/genres.tsv第 6 行正是g05 Animation——所以页面上会直接出现一个预填了Animation的输入框。数据的加载方式沿用 TableInHtmlTable 演示 中的loadTable函数通过store.startTransaction()开启事务、逐行store.setCell(tableId, rowId, cellId, cell)写入数字型字符串会被parseFloat转换、最后store.finishTransaction()提交。第三步样式化编辑面板与类型切换按钮编辑控件渲染为一组「类型按钮 输入控件」结构上是包裹在div里的按钮和输入框见下文原理分析。演示给出了配套的 LESS 样式#edit { align-self: flex-start; background: white; box-shadow: 0 0 1rem #0004; margin: 2rem; min-width: 16rem; padding: 0.5rem 1rem 1rem; } .editableCell { button { width: 4rem; margin-right: 0.5rem; } } input.invalid { background: #fdd; }这里出现了两个与实现密切相关的选择器.editableCell组件根节点的默认 class 是editable与Cell两个字符串的拼接EDITABLE CELL见 common/index.tsx 中export const EDITABLE editable以及 EditableCellView.tsx 中class: props.className ?? EDITABLE CELL。演示用它约束类型切换按钮的宽度。input.invalid当输入内容无法通过 JSON 解析对象/数组类型场景时输入框会被加上invalidclass用来做错误态高亮。具体判定逻辑见下文 EditableThing 的handleJsonThingChange。另外EditableCellView还接受可选的showType属性默认true当设为false时组件会隐藏类型切换按钮只保留值输入控件。第四步一键开启整表编辑——editable 属性单独的单元格编辑只是第一步。TableInHtmlTable本身提供了editable布尔属性置为true后表格内部所有单元格都会改用EditableCellView来渲染从而整张表都变成可编辑的- TableInHtmlTable tableIdgenres / TableInHtmlTable tableIdgenres editable{true}/从源码看这个开关的作用非常直接。TableInHtmlTable.tsx 在构建单元格渲染配置时这样选择组件useCells( useTableCellIds(() props.tableId, () props.store), () props.customCells, () (props.editable ? EditableCellView : CellView), )也就是说editable为真时默认单元格组件从只读的CellView切换为可编辑的EditableCellView为假时保持只读。这一模式同样适用于该系列中的SortedTableInHtmlTable、SliceInHtmlTable、RelationshipInHtmlTable等组件——它们都声明了editable属性见 ui-solid-dom/index.d.ts 中的各 Props 类型。至此改完两处代码后整个genres表格都获得了与独立编辑面板一致的编辑体验。第五步底层原理——EditableThing 与类型循环切换编辑体验并不只是「一个 input」这么简单EditableCellView复用了EditableValueView同一套内部实现EditableThing位于 common/components.tsx。它的核心逻辑可以拆成三部分1. 双向绑定到 Store。组件通过useCellState(tableId, rowId, cellId, store)拿到[cell, setCell]元组见 EditableCellView.tsx。useCellState由 primitives.ts 提供本质是useCell响应式读取底层通过addCellListener订阅 Store 变更与useSetCellCallback调用store.setCell写回的组合。因此外部对同一 Cell 的任何修改都会实时反映到输入框里反向输入框的每一次改动也会立即写入 Store 并触发其他监听者更新。2. 按类型渲染不同控件。EditableThing依据当前值的类型由 cell.ts 的getCellOrValueType判定string / number / boolean / object / array另有null但不可作为可编辑目标用getTypeCase分发控件string → 普通文本inputnumber →input typenumberboolean →input typecheckboxobject / array → 文本input输入内容按 JSON 解析3. 类型循环切换与 JSON 校验。组件头部显示一个按钮按钮文字即当前类型string、number…点击后在string → number → boolean → object → array → string的循环中前进common/components.tsx。切换时会尝试把当前输入按新类型转换例如从 string 切到 number输入值会变成0从 number 切到 boolean则变成复选框。有两个值得注意的细节若 Store 配置了 Tables SchemahasSchema()返回真此时类型按钮被禁用——schema 已经限定了 Cell 的合法类型不允许随意切换见handleTypeChange开头的if (!props.hasSchema?.())守卫。object / array 的输入会经过handleJsonThingChange输入内容用jsonParse解析解析成功且类型匹配才写回 Store否则给输入框加上invalidclass——这正是第三步 CSS 中input.invalid的用武之地。第六步端到端验证——测试用例揭示的交互闭环仓库的端到端测试test/e2e/demos/ui-components.test.ts#L675-L787对同款 React 演示做了完整的行为验证这些断言同样勾勒出 Solid 版组件的交互契约表格内第 5 行对应g05的单元格与#edit面板中的输入框都初始显示Animation且类型按钮均为string点击类型按钮后表格单元格与#edit面板的按钮同步变为number输入框值变为0继续点击依次变为boolean复选框勾选、object、array再循环回string在任一输入框中输入新值另一个输入框立即同步——验证了「多处编辑控件共享同一个 Store 数据源」的响应式闭环。这组断言精确对应了本文第四步的结论独立EditableCellView与editable表格内的单元格操作的是同一条数据链路。关联组件与下一步EditableValueView与EditableCellView几乎对称——前者只接收valueId即可编辑 Store 中的 Value实现与 EditableValueView (Solid) 演示 完全同构两者共用同一个EditableThing。想要深入了解ui-solid-dom各组件的全部配置项如customCells、extraCellsBefore/After、headerRow、idColumn可查阅 TableInHtmlTable (Solid) 演示 与 ui-solid-dom/index.d.ts 中的HtmlTableProps、TableInHtmlTableProps类型。本系列还以 Inspector (Solid) 演示 收尾ui-solid-inspector模块的 Inspector 组件可以在应用内以浮层形式查看并编辑整个 Store。如果你需要的是「面向开发者的数据调试面板」而非「面向用户的单元格编辑」直接跳到那篇即可。赞分享数据库后端前端【免费下载链接】tinybaseA reactive data store sync engine.项目地址https://gitcode.com/gh_mirrors/ti/tinybase点击查看免费下载相关推荐tinybase React 实战用 EditableValueView 组件在浏览器中直接编辑 Store 的 Valuestinybase React 实战用 EditableValueView 组件在浏览器中直接编辑 Store 的 Values 本篇基于 tinybase 官数据库后端前端tinybase 实战在 React 中用 EditableCellView 原地编辑 Store 的 Cell 值tinybase 实战在 React 中用 EditableCellView 原地编辑 Store 的 Cell 值 本文基于 tinybase 官方 Rea数据库后端前端表格单元格点击编辑实战用事件委托与 focus 构建可编辑表格单元格表格单元格点击编辑实战用事件委托与 focus 构建可编辑表格单元格 导读 本文基于 Modern JavaScript Tutorial本仓库 2 ui/文档/教程前端上一篇终极指南如何用biliTickerBuy轻松抢到B站会员购热门门票下一篇智能编辑器集成解决方案如何实现无缝开发环境切换创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考