通过去抖来聆听多范围的值变化

Sof*_*mur 6 javascript underscore.js debouncing lodash office-js

目前,我使用以下代码来听取以下内容的变化Sheet1!A1:B2:

function addEventHandler() {
    Office.context.document.bindings.addFromNamedItemAsync("Sheet1!A1:B2", "matrix", { id: "myBind" }, function (asyncResult) {
        Office.select("binding#myBind").addHandlerAsync(Office.EventType.BindingDataChanged, onBindingDataChanged2016);
    })
}

function onBindingDataChanged2016(eventArgs) {
    Excel.run(function (ctx) {
        var foundBinding = ctx.workbook.bindings.getItem(eventArgs.binding.id);
        var myRange = foundBinding.getRange();
        myRange.load(["address", 'values']);
        return ctx.sync().then(function () {
            console.log(JSON.stringify({ "address": myRange.address, "value": myRange.values }));
            // costly reaction
        })
    })
}
Run Code Online (Sandbox Code Playgroud)

因为我对改变的反应是非常昂贵的,所以我只想在真正需要时才采取这种做法.我有两个问题:

1)如果我想听多范围,是否可以只定义一个监听器"Sheet1!A1:B2, Sheet1!A9:B10, Sheet1!A100:B120"?我是否必须为每个范围添加一个处理程序?

2)是否可以表达I listen only to the change of VALUES,而不是格式等?

可选问题:

是否有可能在某处指定去抖?例如,

  1. 我们初始化一个时钟 0

  2. 如果触发了侦听器,我们会记录binding id更改,并将时钟设置为0

  3. 当时钟到达时1 second(即,它已经安静1秒钟),我们对所有记录的变化作出反应(即,加载所有变化的范围并进行昂贵的反应)

fny*_*fny 1

  1. Office JS 没有允许侦听多个绑定的事件处理程序,就像 HTML 无法同时侦听多个 DOM 节点一样。即使有这样的 API 函数,它也必须在内部创建多个侦听器,因此您不会获得任何性能优势。

  2. 不幸的是,没有可用的事件类型可以区分数字更改和格式更改。

  3. 但是,您可以通过反跳获得巨大的好处!

假设您有一些debounce(func, wait, immediate = false)可用的功能。*

只需将 on Change 函数包装在debounce()调用中即可。

function addEventHandler() {
    Office.context.document.bindings.addFromNamedItemAsync("Sheet1!A1:B2", "matrix", { id: "myBind" }, function (asyncResult) {
        Office.select("binding#myBind").addHandlerAsync(
          Office.EventType.BindingDataChanged,
          debounce(onBindingDataChanged2016, 5000)
        );
    })
}
Run Code Online (Sandbox Code Playgroud)

这将使所有对 的调用去抖onBindingDataChanged2016。如果您想针对每个特定的绑定 ID 进行反跳,事情会变得有点棘手。您必须创建自己的去抖动函数,该函数跟踪每个绑定 id 的超时:

function debounceByBindingId(func, wait, immediate) {
  var timeouts = {};
  return function() {
    var context = this, args = arguments;
    var eventArgs = arguments[0];
    var bindingId = eventArgs.binding.id;

    var later = function() {
      timeouts[bindingId] = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeouts[bindingId]);
    timeouts[bindingId] = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};
Run Code Online (Sandbox Code Playgroud)

*一如既往,在 JavaScript 领域,有太多的选项可供选择!