!!!###!!!title=4.3 内置事件定义及实现——VisActor/VTable 社区贡献者文档!!!###!!!!!!###!!!description=--- title: 4.3 内置事件定义及实现 key words: VisActor,VChart,VTable,VStrory,VMind,VGrammar,VRender,Visualization,Chart,Data,Table,Graph,Gis,LLM --- !!!###!!!

简介

VTable 内部的事件监听了两种类型的事件,分别是原生 DOM 事件、内置自定义事件。

本文将讲解自定义事件的定义,以及 VTable 中自定义事件相关事项。

自定义事件

在前端开发中,Javascript 和 HTML 之间都是通过事件来进行通信,像是失焦、点击、鼠标移动等。事件是一种通信方式,我们可以通过监听事件来完成页面的交互功能。

但是对于复杂的项目,基础事件无法满足业务需求,这时就可以引入自定义事件了**。**

常规的事件采用的是观察者模式,他的触发时机是在用户进行相应操作后进行触发,而自定义事件采用的是发布-订阅的模式,允许开发者自行决定注册与触发时机。

自定义事件需要先进行注册,如下图所示,在E模块中先进行注册和传入对应的回调,随后便可以在其他模块中触发自定义事件,执行对应的回调。

在 VTable 中,自定义模块最主要是用于下面这条链路,当用户进行交互的时候,触发对应的自定义事件,更改状态模块,触发表格组件重新渲染,实现 VTable 中的交互系统。

自定义事件除了用来在各个不同模块之间进行通信以外,还能用来让业务方注册自定义事件,实现自定义逻辑。

内置事件分类

在 VTable 内部,提供了高达 50 多种内置事件,下面根据不同的分类来介绍:

  • 单元格相关

  • CLICK_CELL 鼠标点击单元格事件

  • DBLCLICK_CELL 鼠标双击单元格事件

  • SELECTED_CELL 单元格选中状态改变事件

  • SELECTED_CLEAR 单元格选中状态改变事件

  • DRAG_SELECT_END 拖拽框选单元格鼠标松开事件

  • MOUSEDOWN_CELL 单元格上鼠标按下事件

  • MOUSEUP_CELL 单元格鼠标松开事件

  • MOUSEMOVE_CELL 鼠标在某个单元格上移动事件

  • MOUSEENTER_CELL 鼠标进入单元格事件

  • MOUSELEAVE_CELL 鼠标离开单元格事件

  • CHANGE_CELL_VALUE 更改单元格值的事件

  • COPY_DATA 单元格内容复制事件

  • CONTEXTMENU_CELL 单元格右键事件

  • CONTEXTMENU_CANVAS 画布右键事件

  • 键盘相关事件

  • KEYDOWN 键盘按下事件

  • 表格相关事件

  • MOUSEENTER_TABLE 鼠标进入表格事件

  • MOUSELEAVE_TABLE 鼠标离开表格事件

  • MOUSEDOWN_TABLE 鼠标点击表格事件

  • MOUSEMOVE_TABLE 鼠标在表格上移动事件

  • 行高列宽调整事件

  • RESIZE_COLUMN 列宽调整事件

  • RESIZE_COLUMN_END 列宽调整结束事件

  • RESIZE_ROW 行高调整事件

  • RESIZE_ROW_END 行高调整结束事件

  • 拖拽表头移动位置的事件

  • CHANGE_HEADER_POSITION_START 拖拽表头或者拖拽行来移动位置开始事件

  • CHANGE_HEADER_POSITION 拖拽表头或者行来移动位置的事件

  • CHANGING_HEADER_POSITION 拖拽表头或者拖拽行移动过程事件

  • CHANGE_HEADER_POSITION_FAIL 拖拽表头或者行来移动位置的失败事件

  • 排序相关事件

  • SORT_CLICK *点击排序图标事件。*ListTable 专有事件

  • PIVOT_SORT_CLICK *透视表中排序图标点击事件。*PivotTable 透视表专有事件

  • AFTER_SORT 执行完排序事件。ListTable 专有事件 **

  • 图标事件

  • ICON_CLICK icon 图标点击事件

  • FREEZE_CLICK 点击固定列图标冻结或者解冻事件

  • DRILLMENU_CLICK *下钻按钮点击事件。*透视表专有事件

  • 滚动事件

  • SCROLL 滚动表格事件

  • SCROLL_HORIZONTAL_END 横向滚动到右侧结束事件

  • SCROLL_VERTICAL_END 竖向滚动条滚动到底部事件

  • 迷你图事件

  • MOUSEOVER_CHART_SYMBOL 鼠标经过迷你图标记事件

  • 下拉菜单事件

  • DROPDOWN_MENU_CLICK 下拉菜单选项的点击事件

  • DROPDOWN_ICON_CLICK 点击下拉菜单按钮

  • DROPDOWN_MENU_CLEAR 清空下拉菜单事件(菜单显示时点击其他区域)

  • SHOW_MENU 显示菜单事件

  • HIDE_MENU 隐藏菜单事件

  • 图例事件

  • LEGEND_ITEM_CLICK 图例项点击事件。图例专有事件 **

  • LEGEND_ITEM_HOVER 图例项 hover 事件。图例专有事件 **

  • LEGEND_ITEM_UNHOVER 图例项 hover 到 unhover 事件。图例专有事件 **

  • LEGEND_CHANGE 颜色图例,尺寸图例,用户操作图例范围后触发该事件。图例专有事件 **

  • 透视图坐标轴事件

  • MOUSEENTER_AXIS 鼠标进入到坐标轴上事件。坐标轴专有事件 **

  • MOUSELEAVE_AXIS 鼠标离开坐标轴事件。坐标轴专有事件 **

  • 状态更改

  • CHECKBOX_STATE_CHANGE 更改 checkbox 复选框状态。ListTable 表格专有事件 **

  • RADIO_STATE_CHANGE 更改 radio 单选框状态。ListTable 表格专有事件 **

  • TREE_HIERARCHY_STATE_CHANGE 树形结构展开收起的点击事件

  • 生命周期

  • AFTER_RENDER 每次渲染完成后触发

  • INITIALIZED 成功初始化完成后触发

  • 填充柄事件

  • DRAG_FILL_HANDLE_END 拖拽填充柄结束事件

  • MOUSEDOWN_FILL_HANDLE 拖拽填充柄点击事件

  • DBLCLICK_FILL_HANDLE 拖拽填充柄双击事件

  • 空数据提示

  • EMPTY_TIP_CLICK 空数据提示点击事件

  • EMPTY_TIP_DBLCLICK 空数据提示双击事件

参考文档:

自定义事件的实现

自定义事件的实现,基于EventTarget 模块。

模块内部提供了 on 方法,通过该方法可以实现自定义事件注册的功能,同时自定义事件的类型也可以交由开发者自定义。

// packages\vtable\src\event\EventTarget.ts
export class EventTarget {
  private listenersData: {
    listeners,
    listenerData
  } = {
    listeners: {},
    listenerData: {}
  };
  on(type, listener) {
    const list: TableEventListener<TYPE>[] =
      this.listenersData.listeners[type] || (this.listenersData.listeners[type] = []);
    list.push(listener);

    const id = idCount++;
    this.listenersData.listenerData[id] = {
      type,
      listener,
      remove: (): void => {
        delete this.listenersData.listenerData[id];
        const index = list.indexOf(listener);
        list.splice(index, 1);
        if (!this.listenersData.listeners[type].length) {
          delete this.listenersData.listeners[type];
        }
      }
    };
    return id;
  }
  off(idOrType, listener): void {
      //...
  }
  addEventListener(type, listener, option): void {
      //...
  }
  removeEventListener(type, listener) {
      //...
  }
  hasListeners(type) {
      //...
  }
  fireListeners(type, event){
      //...
  }
  release(): void {
      //...
  }
}    

观察 on 方法,我们可以看到内部对注册的自定义事件回调做了收集,同时为每一个回调分配了唯一id,后续可通过该 id 对回调进行注销操作。

自定义事件的触发则是通过 fireListeners


以双击自动列宽为例:

  • EventManager中注册 DBLCLICK_CELL事件
// packages\vtable\src\event\event.ts
export class EventManager {
    constructor() {
        // ...
        bindSelfEvent();
        // ...
    }
    bindSelfEvent() {
        // ...
            this.table.on(TABLE_EVENT_TYPE.DBLCLICK_CELL, () => {
                // 处理双击自动列宽
            })
        // ...
    }
}
    

  • 在双击事件的回调中,触发 DBLCLICK_CELL 事件,执行处理双击自动列宽的逻辑。
// packages\vtable\src\event\listener\table-group.ts
  eventManager.gesture.on('doubletap', e => {
    dblclickHandler(e, table);
  });
  
  function dblclickHandler(e: FederatedPointerEvent, table: BaseTableAPI) {
      // ...
      table.fireListeners(TABLE_EVENT_TYPE.DBLCLICK_CELL, cellsEvent);
      //...
  }    

事件注册时机

VTable 中大部分的内置事件注册都是在 EventManager 事件管理模块中完成的,其余少部分的内置事件是在其它组件模块中单独去注册的,包括 MenuHandlerEditManagerTooltipHandler 等。我们来简单看下各个模块都注册了哪些事件吧。

  • EventManager

  • ICON_CLICK

  • DROPDOWN_MENU_CLICK

  • DBLCLICK_CELL

  • MOUSEMOVE_CELL

  • MOUSELEAVE_TABLE

  • ...

  • MenuHandler

  • DROPDOWN_ICON_CLICK

  • DROPDOWN_MENU_CLEAR

  • CONTEXTMENU_CELL

  • CONTEXTMENU_CANVAS

  • EditManager

  • DBLCLICK_CELL

  • CLICK_CELL

  • TooltipHandler

  • MOUSEENTER_CELL

  • MOUSEMOVE_CELL

  • MOUSELEAVE_CELL

  • SELECTED_CELL

  • MOUSELEAVE_TABLE

  • SCROLL

  • ...

结语

VTable 中提供了十分丰富的内置事件,通过注册这些内置事件,业务方可以完成绝大多数的自定义业务逻辑,内置事件的存在使得表格能够更具灵活性。

本文档由以下人员提供

taiiiyang(https://github.com/taiiiyang)

本文档由以下人员修正整理

玄魂