2017-03-13 18 views
6

वर्तमान में, मैं Sheet1!A1:B2 के परिवर्तन को सुनने के लिए निम्नलिखित कोड का उपयोग करें:debounce साथ बहु पर्वतमाला के मूल्य में परिवर्तन करने के लिए सुनो

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. के साथ एक घड़ी आरंभ करता है, तो एक श्रोता शुरू हो रहा है, हम परिवर्तन की binding id रिकॉर्ड करते हैं, और 0

  3. जब घड़ी स्थानों पर घड़ी सेट 1 second (यानी, यह 1 सेकंड के लिए चुप रहा है), हम सभी दर्ज परिवर्तनों (यानी, सभी बदली हुई श्रेणियों को लोड करते हैं और महंगी प्रतिक्रिया लेते हैं) पर प्रतिक्रिया करते हैं

उत्तर

1
  1. कार्यालय जेएस में कोई ईवेंट हैंडलर नहीं है जो एकाधिक बाइंडिंग सुनने की अनुमति देता है, जैसे एचटीएमएल के पास कई डोम नोड्स को एक साथ सुनने का कोई तरीका नहीं है। यहां तक ​​कि अगर ऐसा एपीआई फ़ंक्शन था, तो इसे आंतरिक रूप से एकाधिक श्रोताओं को बनाना होगा, इसलिए आपको कोई प्रदर्शन लाभ नहीं मिलेगा।

  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 पर सभी कॉलों को अस्वीकार कर देगा। यदि आप प्रति विशिष्ट बाइंडिंग आईडी को डिबॉन्स करना चाहते हैं, तो चीजें थोड़ा मुश्किल हो जाती हैं। आप अपनी खुद की debounce समारोह है, जो बाध्यकारी आईडी प्रति समय समाप्ति पटरियों बनाने के लिए चाहते हैं:

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

* हमेशा की तरह जावास्क्रिप्ट देश में, वहाँ भी कई विकल्पों में से चुनने के लिए कर रहे हैं!

+0

debounce अच्छी तरह से काम करता है, आपको बहुत बहुत धन्यवाद ... – SoftTimur

+0

एक और debouncing उदाहरण (दस्तावेज़ की घटनाओं के साथ नहीं के लिए , लेकिन बाहरी बटन-क्लिक घटनाएं), इस गिस्ट को देखें: https://gist.github.com/Zlatkovsky/0dd0e7281e70af25d67bdb55cd4d7e4b। आप इसे केवल कुछ क्लिक के साथ चलाने के लिए सीधे [स्क्रिप्ट लैब] (https://github.com/OfficeDev/script-lab/blob/master/README.md#import) में लोड कर सकते हैं। –

संबंधित मुद्दे