找回密码
 立即注册

QQ登录

只需一步,快速开始

nutstore
金牌服务用户   /  发表于:2023-9-25 15:53  /   查看:2164  /  回复:10
1金币
本帖最后由 Clark.Pan 于 2023-9-27 16:10 编辑

产品名称:SpreadJS
版本号:V15.2.5

操作如下动图:
2023-09-25 15.47.07.gif

我的实现思路为,更改 columns 的位置,之后重新 bind 到 table 中,根据我的实现,当我调整完顺序之后,状态列的列名显示为了 ”状态2“;

代码如下:
  1.   const handleMoveColumn = usePersistFn((src: number, dest: number) => {
  2.     const newColumn = move(src, dest, spreadDataColumns)
  3.     activeSheet.suspendCalcService(false)
  4.     const table = activeSheet.tables.findByName('table1')
  5.     activeSheet.setColumnCount(newColumn.length + 20)
  6.     const tableColumns = newColumn.map((item, index) => {
  7.       return new Spread.Sheets.Tables.TableColumn(
  8.         index,
  9.         item.binding,
  10.         item.name,
  11.         item.dataType === 'Date' ? 'yyyy-MM-dd' : undefined,
  12.         undefined,
  13.         needNameMapFields.includes(item.binding)
  14.           ? (value: Record<string, any>) => {
  15.               return (
  16.                 accountSvc.getAccountSync(value[item.binding])?.displayName ||
  17.                 ''
  18.               )
  19.             }
  20.           : needTicketStatusMapFields.includes(item.binding)
  21.           ? (value: Record<string, any>) => {
  22.               return ticketStatusDataMap.get(value[item.binding]) || ''
  23.             }
  24.           : undefined,
  25.       )
  26.     })
  27.     table.bind(tableColumns, undefined, spreadViewData)
  28.     activeSheet.resumeCalcService(true)
  29.     setSpreadDataColumns(newColumn)
  30.   })
复制代码

根据这个思路,第二次 bind table 的表头出现了问题。
我更改 Column 的方式是否标准?如果不标准,那么标准的方式是什么?
为什么我更改之后的Column 中的 ”状态“ 变为了 ”状态2“?这个是什么原因呢?应该怎么修复。



DEMO 交换表格列顺序.html (6.36 KB, 下载次数: 118)

最佳答案

查看完整内容

您好,我已复现您的问题,首先解释一下原因,在切换顺序的时候我们使用table.bind方法来实现, 该方法的底层是一条数据一条数据进行刷新的 例如,咱们刚开始的顺序是“姓名、年龄、地址” 我们希望切换后的顺序是“地址、年龄、姓名”,那么它的底层实现就是 1. 将地址刷新上去:变成“地址、年龄、地址”(地址重复,变成地址2) 2. 将年龄刷新上去:变成“地址2、年龄、地址” 3. 将姓名刷新上去:变成“地址2、年龄、 ...

10 个回复

倒序浏览
最佳答案
最佳答案
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2023-9-25 15:53:16
来自 9#
本帖最后由 Richard.Huang 于 2023-9-26 15:49 编辑
nutstore 发表于 2023-9-26 14:46
还是没有解决,我把demo放在 正文的最下面了,你试试,这个是可以复现的

您好,我已复现您的问题,首先解释一下原因,在切换顺序的时候我们使用table.bind方法来实现,
该方法的底层是一条数据一条数据进行刷新的
例如,咱们刚开始的顺序是“姓名、年龄、地址”

我们希望切换后的顺序是“地址、年龄、姓名”,那么它的底层实现就是
1. 将地址刷新上去:变成“地址、年龄、地址”(地址重复,变成地址2)
2. 将年龄刷新上去:变成“地址2、年龄、地址”
3. 将姓名刷新上去:变成“地址2、年龄、姓名”

如果我们希望切换后的顺序是“年龄、地址、姓名”,那么它的底层实现就是
1. 将年龄刷新上去:变成“年龄、年龄、地址”(年龄重复,变成年龄2)
2. 将地址刷新上去:变成“年龄2、地址、地址”(地址重复,变成地址2)
3. 将姓名刷新上去:变成“年龄2、地址2、姓名”

因此为了避免该问题的出现,我们有两种解决方案,第一种就是我上面给的Demo中用的方法:
table.bindColumns([tableColumn3, tableColumn2, tableColumn1]);
table.bindingPath("table")

或者您在更改顺序之前将原有的table销毁,就像下面这样:
_getElementById("check").addEventListener("click", function () {
  sheet.tables.remove(sheet.tables.all()[0]);// 晒出原有表格
  const columns = [
    { binding: "age", name: "年龄", dateType: "Number" },
    { binding: "address", name: "地址", dateType: "String" },
    { binding: "name", name: "姓名", dateType: "String" },
  ];

  const table = sheet.tables.add("table1", 0, 0, data.table.length, columns.length);// 添加新的表格
  table.autoGenerateColumns(false);// 不允许自动扩展
  const tableColumns = columns.map((item, index) => {
    return new GC.Spread.Sheets.Tables.TableColumn(
      index,
      item.binding,
      item.name,
      item.dataType
    );
  });
  table.bind(tableColumns, undefined, data.table);
});

回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2023-9-25 18:18:11
2#
您好,出现数字2的原因是因为您的绑定信息中存在重复的绑定路径,例如:
image.png682588500.png
image.png968730163.png
我注意到您交换字段顺序后,没有勾选的“负责人”展示了出来,因此我们怀疑您在代码逻辑细节上可能有问题,您可以先排查一下您的代码,如果找不到问题原因,请提供一份可供我们复现的代码Demo,方便我们更好地为您解决问题
回复 使用道具 举报
nutstore
金牌服务用户   /  发表于:2023-9-26 10:00:15
3#
Richard.Huang 发表于 2023-9-25 18:18
您好,出现数字2的原因是因为您的绑定信息中存在重复的绑定路径,例如:

"负责人" 是我隐藏的数据,脱敏。

但是按道理,我是重新绑定的列呀,为啥还会出现这个问题呢?是否可以在此之前对上一个列进行销毁的API?
回复 使用道具 举报
nutstore
金牌服务用户   /  发表于:2023-9-26 10:08:38
4#
Richard.Huang 发表于 2023-9-25 18:18
您好,出现数字2的原因是因为您的绑定信息中存在重复的绑定路径,例如:

这个是初始化的代码:
  1. const fetchData = usePersistFn(
  2.     async (
  3.       columnDataBindings: string[],
  4.       spreadDataColumns: ColumnSchemaUnion[],
  5.     ) => {
  6.       let dataTotal: string | null = null
  7.       请求数据。。。
  8.       if (spreadWorkbook && activeSheet) {
  9.         activeSheet.suspendPaint()
  10.         activeSheet.setRowCount(dataTotal ? Number(dataTotal) + 50 : 200)
  11.         activeSheet.setColumnCount(spreadDataColumns.length + 20)
  12.         const Json = window.localStorage.getItem(
  13.           `spreadViewSummary_${templateId}`,
  14.         )

  15.         if (!Json) {
  16.           activeSheet.tables.add(
  17.             'table1',
  18.             0,
  19.             0,
  20.             lists.length,
  21.             spreadDataColumns.length,
  22.           )
  23.         }
  24. 创建表格即初始化
  25.         const table = activeSheet.tables.findByName('table1')
  26.         table.showHeader(true)
  27.         table.style(Spread.Sheets.Tables.TableThemes.medium7)
  28.         const tableColumns = spreadDataColumns.map((item, index) => {
  29.           activeSheet.setColumnWidth(index, 200)
  30.           return new Spread.Sheets.Tables.TableColumn(
  31.             index,
  32.             item.binding,
  33.             item.name,
  34.             item.dataType === 'Date' ? 'yyyy-MM-dd' : undefined,
  35.             undefined,
  36.             needNameMapFields.includes(item.binding)
  37.               ? (value: Record<string, any>) => {
  38.                   return (
  39.                     accountSvc.getAccountSync(value[item.binding])
  40.                       ?.displayName || ''
  41.                   )
  42.                 }
  43.               : needTicketStatusMapFields.includes(item.binding)
  44.               ? (value: Record<string, any>) => {
  45.                   return ticketStatusDataMap.get(value[item.binding]) || ''
  46.                 }
  47.               : undefined,
  48.           )
  49.         })

  50.         table.autoGenerateColumns(false)

  51.         table.bind(tableColumns, undefined, lists)

  52.         activeSheet.suspendCalcService(false)

  53.       
  54.         // 禁止数据范围的单元格编辑
  55.         const style = new Spread.Sheets.Style()
  56.         style.locked = false
  57.         activeSheet
  58.           .getRange(lists.length + 1, 0, 50, spreadDataColumns.length + 20)
  59.           .setStyle(style)
  60.         activeSheet
  61.           .getRange(0, spreadDataColumns.length, lists.length + 50, 20)
  62.           .setStyle(style)

  63.         activeSheet.options.isProtected = true

  64.         activeSheet.resumeCalcService(true)

  65.   

  66.         activeSheet.resumePaint()
  67.       }
  68.       setSpreadViewData(lists)
  69.     },
  70.   )
复制代码
回复 使用道具 举报
nutstore
金牌服务用户   /  发表于:2023-9-26 10:09:20
5#
Richard.Huang 发表于 2023-9-25 18:18
您好,出现数字2的原因是因为您的绑定信息中存在重复的绑定路径,例如:

主要就是这两个逻辑,再没有别的操作了。
回复 使用道具 举报
nutstore
金牌服务用户   /  发表于:2023-9-26 11:19:19
6#
SpreadJS 中的tables 是否支持列的拖拽排序?
如果不行,按照我的写法,是否可以支持在重新bind 之后保持筛选信息不变?
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2023-9-26 13:47:40
7#
本帖最后由 Richard.Huang 于 2023-9-26 13:49 编辑

您好,对于您的疑问,我们的回答是:
1. SpreadJS 中的tables不支持列的拖拽排序,您可以按照您的想法,排序之后重新绑定
2. 重新绑定之后筛选信息是不会保存的,因此想要保持筛选信息不变,需要自己来实现,我们有相关的方法可以获取表格的筛选信息,您在重新绑定之前对它进行记录,重新绑定之后再将筛选信息添加进去即可,获取和添加筛选信息的方法为getFilterItemsaddFilterItem
实现方式您可以参考:
// 交换顺序
_getElementById("check").addEventListener('click', function () {
    var tableColumn1 = new GC.Spread.Sheets.Tables.TableColumn();
    tableColumn1.name("Name");
    tableColumn1.dataField("name");
    var filterItems1 = table.rowFilter().getFilterItems(0);

    var tableColumn2 = new GC.Spread.Sheets.Tables.TableColumn();
    tableColumn2.name("Age");
    tableColumn2.dataField("age");
    var filterItems2 = table.rowFilter().getFilterItems(1);


    var tableColumn3 = new GC.Spread.Sheets.Tables.TableColumn();
    tableColumn3.name("Address");
    tableColumn3.dataField("address");
    var filterItems3 = table.rowFilter().getFilterItems(2);

    // 绑定新的列信息
    table.bindColumns([tableColumn3, tableColumn2, tableColumn1]);
    table.bindingPath("table")

    // 按照新的顺序将之前的筛选信息更新上去
    if (filterItems1.length != 0) {
        table.rowFilter().addFilterItem(2, filterItems1)
        table.rowFilter().filter(2)
    }

    if (filterItems2.length != 0) {
        table.rowFilter().addFilterItem(1, filterItems2)
        table.rowFilter().filter(1)
    }

    if (filterItems3.length != 0) {
        table.rowFilter().addFilterItem(0, filterItems3)
        table.rowFilter().filter(0)
    }
})

3. 对于您绑定后有问题目前从您给的信息来看无法准确知道原因所在,建议您将红框内tableColumns打印出来看一下您新绑定的信息是否准确,是否符合您的预期,以及对绿色箭头处的setSpreadDataColumns方法进行排查解释
image.png270038146.png


最后,还是希望能够提供一份可供我们复现的代码Demo,方便我们为您查找问题所在

交换表格列顺序.html

7.52 KB, 下载次数: 120

回复 使用道具 举报
nutstore
金牌服务用户   /  发表于:2023-9-26 14:46:54
8#
Richard.Huang 发表于 2023-9-26 13:47
您好,对于您的疑问,我们的回答是:
1. SpreadJS 中的tables不支持列的拖拽排序,您可以按照您的想法,排 ...

还是没有解决,我把demo放在 正文的最下面了,你试试,这个是可以复现的
回复 使用道具 举报
nutstore
金牌服务用户   /  发表于:2023-9-26 16:37:03
10#
Richard.Huang 发表于 2023-9-26 15:47
您好,我已复现您的问题,首先解释一下原因,在切换顺序的时候我们使用table.bind方法来实现,
该方法的 ...

结合我发你的DEMO,第一种方案无效,第二种有效
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部