2017-03-13 41 views
6

目前,我使用下面的代碼來聽的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秒),我們對所有記錄的變化作出反應(即加載所有變化的範圍並承擔昂貴的反應)

回答

1
  1. Office JS沒有允許監聽多個綁定的事件處理程序,就像HTML如何無法同時監聽多個DOM節點一樣。即使有這樣一個API函數,它也不得不在內部創建多個監聽器,所以你不會獲得性能優勢。

  2. 不幸的是,有no event type available區分數字更改和格式更改。

  3. 但是,您可以消除很多好處!

讓我們假設你已經有了一些可用的功能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的土地,有太多可供選擇的方案!

+0

去抖效果很好,非常感謝你... – SoftTimur

+0

對於另一個去抖動例如(不與文檔事件,但外部按鈕點擊事件),請參閱此要點: https://gist.github.com/Zlatkovsky/0dd0e7281e70af25d67bdb55cd4d7e4b。您可以直接將它加載到[Script Lab](https://github.com/OfficeDev/script-lab/blob/master/README.md#import),只需點擊幾下即可運行它。 –