【问题标题】:Listen to the value change of multi ranges with debounce用 debounce 监听多范围的值变化
【发布时间】:2017-08-03 18:22:39
【问题描述】:

目前我用下面的代码来监听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,而不是格式等?

选题:

是否可以在某处指定去抖动?例如,

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

  2. 如果监听器被触发,我们记录变化的binding id,并将时钟设置为0

  3. 当时钟到达1 second(即它已经安静了1秒)时,我们对所有记录的变化做出反应(即加载所有变化的范围并承担代价高昂的反应)

【问题讨论】:

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


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

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

    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)
            );
        })
    }
    

    这将消除对onBindingDataChanged2016 的所有调用。如果您想针对每个特定的绑定 id 去抖动,事情会变得有点棘手。您必须创建自己的 debounce 函数,该函数跟踪每个绑定 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 领域,有太多的选项可供选择!

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 2011-10-05
    • 2012-06-25
    • 2021-10-30
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多