devextreme-vue的DxDataGrid如何显示行号列

devextreme-vue我使用的是23.2版本,其DxDataGrid如何显示行号列,官方一直没有方案。

DataGrid - How to display a row number in data rows in Angular | DevExpress Support

dxDataGrid - provide capability to display a column with row numbers | DevExpress Support

因为涉及到分页、分组、统计,等等,其row.rowType有:“data”、"detail"、"detailAdaptive"、groupFooter"、"header"、"filter"、"totalFooter"、“group”这很多种,我们想要的是计算“data”类型的行的行号。rowInfo的rowIndex,dataIndex,loadIndex都不能真实的反映“资料行号”,用pageIndex*pageSize+rowIndex+1计算都是错误的。

看起来自己在dataSource中为每个row计算一个rowNumber值可能比较靠谱。要考虑几个问题:

(1)计算的时机:

  1. 点击column排序,
  2. 拖动column分组,
  3. filter栏打入文字,
  4. 搜索框打入文字,
  5. 增加、删除一行资料
  6. dataSouce改变
  7. ...

前面5个,可以监听option-changed事件:

<template>
<DxDataGrid ref="gridBackend" @option-changed="onOptionChanged" />
</template>

<script setup>
import { ref, nextTick, onMounted, onUnmounted, watch } from 'vue';
import {
  DxDataGrid, DxColumn, DxPager, DxPaging, DxGroupPanel,
  DxSearchPanel, DxSearch, DxLoadPanel, DxEditing,
  DxColumnChooser, DxSelection, DxColumnFixing,
  DxFilterRow, DxFilterPanel, DxHeaderFilter, DxSorting,
  DxScrolling, DxSummary, DxTotalItem
} from 'devextreme-vue/data-grid';
import { DxTabPanel, DxItem as DxTabPanelItem } from 'devextreme-vue/tab-panel';
import ArrayStore from 'devextreme/data/array_store';
import DataSource from 'devextreme/data/data_source'
let gridBackend = ref();

const onOptionChanged = function (e) {
  //console.log(e);
  if (
    e.fullName.includes('filter') ||
    e.fullName.includes('sort') ||
    e.fullName.includes('group') ||
    e.fullName.includes('search') ||
    e.fullName == 'editing.changes'
  ) {
      nextTick(function () {
        recomputeRowNumber(gridBackend.value, dataSourceBackendMonitors.value);
      });
  }
}
</script>

第6个是你改变数据集的时候。

(2)如何对数据集排序过滤;

DxDataGrid在排序过滤时,不会改变原始数据集,我想找到它处理后的数据集,然后计算一个rowNumber,但是翻了源码,它没有保存这个完整的排序过滤后的数据集。但找到一些方法来计算,不用自己写计算逻辑。

function recomputeRowNumber(dxGrid, dataSet) {
  let dc = dxGrid.instance.getController('data');
  let ds = dxGrid.instance.getDataSource();
  /**
   * 不能通过ds.loadOptions();获取参数,获取到的ops是store中的,赋值filter后,它会存起来,
   * 过滤行的filtervalue清掉后,dc.getCombinedFilter还是会从store返回之前的。
   */
  //let ops = ds.loadOptions();
  //ops.filter = dc.getCombinedFilter();
  // console.log('参数:',ds.filter(),dc.getCombinedFilter());

  let ops = {
    requireTotalCount: false,
    filter: dc.getCombinedFilter(),
    group: ds.group(),
    sort: ds.sort()
  }
  //console.log('参数:',ops);
  //ds.store().load(ops)
  new ArrayStore(dataSet).load(ops)
    .done(function (items) {
      //console.log('买', ops, items);
      let rowNumber = 0;
      let groupLevels = -1;
      if (ops.group) groupLevels = ops.group.length;
      function modifyRecords(items, groupLevel) {
        items.forEach(function (item) {
          if (groupLevel < groupLevels) {
            modifyRecords(item.items, groupLevel + 1);
          }
          else {
            rowNumber++;
            item.rowNumber = rowNumber;
          }
        });
      }
      modifyRecords(items, 0);
    });
}

(3)如何显示

想显示在最左边,不要受分组列影响,需要把分组列放在第2列,设定一个type="groupExpand"的列:

<DxColumn data-field="OID" width="50" :visible="false" :fixed="true" :allow-filtering="false"
            :allow-sorting="false" :allow-grouping="false" :allowEditing="false" :allowAdding="false" />
            
          <DxColumn caption="#" data-field="rowNumber" width="50" alignment="center" :fixed="true"
            :allow-filtering="false" :allow-sorting="false" :allow-grouping="false" :allowEditing="false"
            :allowAdding="false" />
          <DxColumn type="groupExpand" />

 (4)优化

  1. 因为是在nextTick之中,即渲染后再修改,因此rowNumber列会有个闪烁,不知如何避免。
  2. optionChanges事件,在打入过滤值时可能会触发3次,如何防抖?用一个timer:
    let recomputeRowNumberTimer;
    const onOptionChanged = function (e) {
      ...
      nextTick(function () {
            if (recomputeRowNumberTimer) clearTimeout(recomputeRowNumberTimer);
            recomputeRowNumberTimer=setTimeout(function(){
              recomputeRowNumber(gridBackend.value, dataSourceBackendMonitors.value);
            },0);
          });

效果为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火星牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值