请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

QQ登录

只需一步,快速开始

Matthew.Xue

超级版主

7

主题

581

帖子

958

积分

超级版主

Rank: 8Rank: 8

积分
958
Matthew.Xue
超级版主   /  发表于:2025-3-12 17:41  /   查看:48  /  回复:0
本帖最后由 Matthew.Xue 于 2025-3-12 17:45 编辑

背景
image.png783709411.png
范围选择器(FormulaTextBox)是SpreadJS和Excel中一个非常常见的功能,它可以非常方便地选择表格中的区域,并拿到被选择区域的引用字符串,除了上图的名称管理器,范围选择器还在其他地方被广泛地使用,比如数据验证、条件格式、图表数据源、数据透视表等。
SpreadJS作为一款控件,开发者可以根据自己的业务开发定制化的功能,有些开发者可能想要在用户确认选择时监做一些事情,比如检查用户选择的范围是否合法,或者根据用户的选择做不同的提示等等,但在目前的版本,FormulaTextBox还没有这样的监听函数,我们只能通过主动调用FormulaTextBox:text方法来获取到选择的范围,代码不能在用户确认选择的第一时间知道,这自然会影响到最终用户的体验。
监听确认选择
其实这个监听是可以通过一些间接的方式做到的。
尽管在官方的api文档中没有体现,但是FormulaTextBox内部其实有一个endSelectMode方法,不论是通过右上角的关闭按钮,还是通过输入框右侧的确认选择,实际上都是通过调用endSelectMode方法让选择框消失的。
image.png722438659.png
那么我们就可以考虑通过重写endSelectMode方法,实现对选择框确认/关闭的监听了:
  1. GC.Spread.Sheets.FormulaTextBox.FormulaTextBox.prototype.valueChanged = function() {
  2.     console.log("changed")
  3. }
  4. let oldF = GC.Spread.Sheets.FormulaTextBox.FormulaTextBox.prototype.endSelectMode
  5. GC.Spread.Sheets.FormulaTextBox.FormulaTextBox.prototype.endSelectMode = function() {   
  6.     this.valueChanged()
  7.     return oldF.apply(this, arguments)
  8. }
复制代码
其中,valueChanged方法就是我们定义的监听函数了,开发者可以在内部实现自己的代码逻辑。
当然,细心的开发者可能会发现,这里的valueChanged事件不仅会在值变化时被触发,在值没有变化时也会触发,而且会触发多次。
image.png264388426.png
的确是这样,这是因为我们没有用一个变量来记录原先的值,加上相关代码:
  1. let oldValue
  2. GC.Spread.Sheets.FormulaTextBox.FormulaTextBox.prototype.valueChanged = function(info) {
  3.     console.log(info)
  4. }
  5. let oldF = GC.Spread.Sheets.FormulaTextBox.FormulaTextBox.prototype.endSelectMode
  6. GC.Spread.Sheets.FormulaTextBox.FormulaTextBox.prototype.endSelectMode = function() {   
  7.     // 只有选择的值发生变化时,触发监听函数
  8.     if(oldValue != this.text()) {
  9.         this.valueChanged({
  10.             oldValue: oldValue,
  11.             newValue: this.text()
  12.         })
  13.         oldValue = this.text()
  14.     }
  15.     return oldF.apply(this, arguments)
  16. }
复制代码
加上这段代码后,我们试试效果:
image.png933623351.png
非常完美!

最后还有一个疑问,为何不将oldValue挂在formulaTextBox中,而是要单独定义呢?这是因为每次打开范围选择器时,其实都是新创建了一个实例,如果要挂上原先的值,就要去修改构造函数了,这里就留给读者自己实现吧~

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部