Angular NgZorro表格如何将数据库排序函数字符串转为NzTableSortFn
问题原因
你报错的核心原因有两个:
- JSON 标准本身不支持函数类型,你存储的
sortFnString是函数字符串,不属于合法JSON格式,调用JSON.parse自然会抛出语法错误。 - 你的代码里把解析结果赋值给了
sortOrder字段,而你实际需要赋值的是sortFn字段,属于字段赋值错误。
推荐解决方案(无安全风险)
不要直接在数据库存储完整函数字符串,改为存储排序规则元数据,前端根据元数据统一生成排序函数,这是最安全也最易维护的方案。
- 数据库jsonb字段存储内容示例:
{ "sortKey": "name", "sortType": "string" }
- 前端生成排序函数的逻辑示例:
tables.pipe( map(tables => { tables.forEach(t => { t.columnsDefinition.forEach(definition => { // 先解析存储的排序元数据 const sortMeta = JSON.parse(definition.sortFnString); // 根据元数据生成对应排序函数 definition.sortFn = (a: any, b: any) => { const valA = a[sortMeta.sortKey]; const valB = b[sortMeta.sortKey]; switch(sortMeta.sortType) { case 'string': return valA.localeCompare(valB); case 'number': return valA - valB; case 'date': return new Date(valA).getTime() - new Date(valB).getTime(); default: return 0; } } as NzTableSortFn; }) }) }) )
函数字符串直接转函数方案(有安全风险)
如果你确实需要直接存储完整函数字符串,可以用Function构造函数或者eval实现转换,但只有你完全信任存储的函数字符串来源、确认没有注入风险时才能使用,如果数据库内容被篡改,会导致恶意代码执行。
转换代码示例:
tables.pipe( map(tables => { tables.forEach(t => { t.columnsDefinition.forEach(definition => { // 方法1:用Function构造函数 definition.sortFn = new Function(`return ${definition.sortFnString}`)() as NzTableSortFn; // 方法2:用eval // definition.sortFn = eval(definition.sortFnString) as NzTableSortFn; }) }) }) )
常见问题说明
- 能不能直接在JSON里存储排序函数不用转换?
不行,JSON标准仅支持字符串、数字、布尔值、数组、对象、null六种数据类型,不支持函数类型,必须通过序列化/反序列化逻辑转换。
内容的提问来源于stack exchange,提问作者SmartOver
相关产品推荐
相关产品推荐

