在教务系统里填一条排课记录,先选授课老师,再选科目。张老师教英语、语文、数学,李老师只带体育、音乐、美术——如果第二个下拉框永远列出全部科目,选课人就可能组合出"李老师-数学"这种不存在的排课。Excel 里大家习惯用"数据验证加 INDIRECT 函数"做二级联动,到了 Web 表单里,这套习惯该怎么延续?
为什么这个细节重要
级联选择看似小交互,实际挡住的是脏数据。下拉框的价值在于把自由输入收窄成合法选项,而联动的价值在于让选项随上下文进一步收缩:选了 A,B 列就只剩和 A 匹配的内容。没有联动,用户照样能选出非法组合,等后端校验报错再回头修改,录入体验和数据质量都受损。
对产品经理来说,这是"防错优先于纠错"这条表单设计原则的具体落点;对开发者来说,关心的是表格控件能不能在单元格级别挂下拉框、能不能在下拉值变化的瞬间插入自己的业务逻辑。SpreadJS 作为 JavaScript 电子表格控件,这两点都有直接的 API 支持。
SpreadJS 的实现思路
整个联动由三部分组成:两个 ComboBox 单元格类型、一次事件绑定、一段选项映射。
先创建下拉框并应用到单元格:
let combo1 = new GC.Spread.Sheets.CellTypes.ComboBox();
combo1.items([
{ text: '张老师', value: 'MrZhang' },
{ text: '王老师', value: 'MrWang' },
{ text: '李老师', value: 'MrLi' }]);
sheet.setCellType(3, 2, combo1, GC.Spread.Sheets.SheetArea.viewport);
combo1.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value);
每个选项携带 text 和 value 两个字段,text 是界面显示的中文名,value 是写进数据模型的代码。editorValueType 设为 EditorValueType.value 之后,单元格实际存的是 MrZhang 这类编码,业务判断和后续存库都不必再做文本解析。
关键的下一步是监听 ValueChanged 事件:
sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function(e, info) {
if (info.row == 3 && info.col == 2) {
let value = info.newValue;
if (value == "MrWang") {
combo2.items([{ text: '历史', value: 'Lishi' } /* ... */]);
sheet.setValue(3, 3, "Lishi");
}
}
});
ValueChanged 在单元格子编辑器中的值发生变化时触发,回调参数里能拿到 row、col、oldValue、newValue。这里按行列号判断变化是否来自 C4,是的话就用新的 items 替换 D4 下拉框的选项列表,并顺手通过 setValue 写入一个默认值,避免 D4 残留上一组组合里的旧选项。
有三点值得展开。第一,items 可以随时重设,所以选项不必写死在前端,完全可以启动时从接口拉取映射表,运行时按需替换。第二,事件回调里按硬编码行列号判断,真实项目建议封装成通用的级联配置,比如声明"C 列变化刷新 D 列"的映射数组,多个级联列并存时不会互相打架。第三,如果选项本身维护在工作表区域或数据库里,还可以用 dataBinding 让下拉框直接读取数据源,联动时同样只需要重设这一份绑定。
可以扩展到哪些场景
同样的套路可以直接搬进很多业务表:省市区三级地址,选了省刷新市、选了市刷新区;商品类目与规格,选了类目只留对应规格;报销单里费用类型决定科目选项;工单系统里产品线决定模块列表;生产排程里车间决定可用产线。凡是前一项收窄后一项的填报场合都能套用,而且交互都发生在表格内部,不需要额外的弹窗或浮层。
给开发者的关键词
GC.Spread.Sheets.CellTypes.ComboBox、items、editorValueType、EditorValueType.value、setCellType、GC.Spread.Sheets.Events.ValueChanged、newValue、Worksheet.setValue、级联下拉框、单元格类型联动。
小结
下拉框解决"输入受控",联动解决"选项相关"。SpreadJS 把这两件事放进了单元格类型和事件的组合里:ComboBox 负责呈现和取值,ValueChanged 负责把业务规则接进来。几十行代码,就能让 Web 表格具备 Excel 里要绕一圈才做得到的级联体验,这也是这类组合在表单密集型应用里被反复使用的原因。