handsontable文档对于数据源的说明:handsontable.com/docs/7.1.1/…
在官方文档中,支持的数据源结构支持以下几种:
- Array data source
- Array data source with hidden columns
- Object data source
- Object data source with column as a function
- Object data source with column mapping (nested)
- Object data source with custom data schema
- Function data source and schema
官方推荐使用前两种数据结构:
data = [
['', 'Tesla', 'Nissan', 'Toyota', 'Honda', 'Mazda', 'Ford'],
['2017', 10, 11, 12, 13, 15, 16],
['2018', 10, 11, 12, 13, 15, 16],
['2019', 10, 11, 12, 13, 15, 16],
['2020', 10, 11, 12, 13, 15, 16],
['2021', 10, 11, 12, 13, 15, 16]
]
二维数组内每一项子数组代表行,每一项代表列;但这种数据结构并不满足我们的要求,我们希望每一项数据都是一个对象,这样我们可以把样式信息也存储到数据中;
而通过阅读其它Object数据结构,发现官方使用的方式都是一个对象代表一行表格:
这与我的期望不符,我希望一个对象中的数据代表一个单元格,而不是代表一整行:
[
[{ name: '' }, { name: 'Ford' }, { name: 'Tesla' }, { name: 'Toyota' }, { name: 'Honda' }],
[{ name: '2017' }, { name: 10 }, { name: 11 }, { name: 12 }, { name: 13 }],
[{ name: '2018' }, { name: 20 }, { name: 11 }, { name: 14 }, { name: 13 }],
[{ name: '2019' }, { name: 30 }, { name: 15 }, { name: 12 }, { name: 13 }]
]
直接这么使用的话,效果是这样的...( 高能来了 )
如果要正常展示,我们可以通过renderer钩子,手动修改表格的innerHTML:
renderer: (instance, TD, row, col, prop, value, cellProperties) => {
TD.innerHTML = value.name
}
这时效果正常了,但此时如果编辑表格的话,高能又来了...
导致这种情况的原因,显而易见是单元格保存的数据是引用类型而不是基本类型,双击表格后会执行toString()方法,那么有没有一种方法可以实现在双击表格的时候修改源数据的内容呢?
当然有,在honsontable的实例中,通过handsontable.editors.BaseEditor可以获得一个构造函数,在它的原型中有两个hook,分别是在编辑表格前的prepare和表格编辑后saveValue,我们可以在prepare时重设value的值,来保证正常显示:
const CustomEditor = Handsontable.editors.BaseEditor
CustomEditor.prototype.prepare = function(row, col, prop, td, value, cellProperties) {
this.originalValue = value.name
}
此时双击表格后展示的内容就正常了,但编辑文本后,原本又还原回初始的样式,这时saveValue就派上用场了:
CustomEditor.prototype.saveValue = function(value, ctrlDown) {
// 编辑表格后将新的值插入到原数组对象中
_this.originData[this.row][this.col]['name'] = value
// 手动渲染表格saveValue期间不会重新renderer表格,需要手动触发渲染
_this.hot.render()
}
saveValue方法的第一个参数时修改后的值,我们只需将源数据name的值修改为传参的值就行,但要注意,修改值并不会触发表格渲染,也就是之前提到的renderer钩子,所以展示的值还是不会变化的,需要我们手动调用render方法才行