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

时间:2017-03-13 16:25:41

标签: javascript underscore.js lodash office-js debouncing

目前,我使用以下代码来聆听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
        })
    })
}

因为我对变化的反应非常强烈,所以我只想在真正需要的时候才采取行动。我有两个问题:

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

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

可选问题:

是否可以在某处指定 debounce ?例如,

  1. 我们使用0

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

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

1 个答案:

答案 0 :(得分:1)

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

  2. 不幸的是,no event type available区分了数字更改和格式更改。

  3. 然而,你可以为了很大的利益辩护!

  4. 让我们假设你有一些功能debounce(func, wait, immediate = false)可用。*

    只需在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)
            );
        })
    }
    

    这将取消对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);
      };
    };
    

    *与JavaScript一样,有太多选项可供选择!

相关问题