0

Background

I am writing a sidebar app for Excel 2013, and I have a wrapper function which updates the view of the sidebar. I need to trigger that function (and so trigger an update of the view) from multiple events, one of which is when the data in a bound area changes.

The problem I'm having is that I need to pass along a variable to that wrapper function. It needs data which I want to be able to save in a Setting and then load just once.


Code

Current Code:

Office.select("bindings#"+bindingID).addHandlerAsync(Office.EventType.BindingDataChanged, onBindingDataChanged);

function onBindingDataChanged(eventArgs) {
    searchThroughData(eventArgs.binding.id);
}
function searchThroughData(bindingID) {
    //repaint view
}

The above works to trigger the repaint. But it doesn't include the passed variable. What I'd expect is for the code to be something like this:

Attempted, Doesn't Work:

Office.select("bindings#"+bindingID).addHandlerAsync(Office.EventType.BindingDataChanged, onBindingDataChanged(eventArgs,data));

function onBindingDataChanged(eventArgs,data) {
    searchThroughData(eventArgs.binding.id,data);
}
function searchThroughData(bindingID,data) {
    //repaint view
}

This doesn't work, however.


Question

Any ideas how I can pass along this variable?

Community
  • 1
  • 1
Kelderic
  • 6,502
  • 8
  • 46
  • 85
  • Where does the variable "data" come from? – bmavity Oct 12 '14 at 14:32
  • It's a setting that is retrieved via `Office.context.document.settings.get('bindingIDs');`. It is being used in a search box which updates on every keystroke, but the setting doesn't change every time, so I want to avoid querying the setting over and over. – Kelderic Oct 12 '14 at 14:35
  • At the moment I'm creating a semi-global variable, inside my top self initiating function but outside my `Office.initialize = `. That seems sloppy, though. – Kelderic Oct 12 '14 at 14:36

1 Answers1

2

In your attempted solution, you are calling the onBindingDataChanged function instead of making it available for the handler to call. You'd need to do something like this (assuming that the variable "data" is available beforehand)

Office.select("bindings#"+bindingID).addHandlerAsync(Office.EventType.BindingDataChanged, onBindingDataChanged(data));

function onBindingDataChanged(data) {
    return function(eventArgs) {
        searchThroughData(eventArgs.binding.id, data);
    };
}

function searchThroughData(bindingID,data) {
    //repaint view
}

If data is a global variable, you can just do

Office.select("bindings#"+bindingID).addHandlerAsync(Office.EventType.BindingDataChanged, onBindingDataChanged(data));

function onBindingDataChanged(eventArgs) {
    searchThroughData(eventArgs.binding.id, data);
}

function searchThroughData(bindingID,data) {
    //repaint view
}
bmavity
  • 2,477
  • 2
  • 24
  • 23
  • That works, thanks! Could you explain how data gets passed through the returned function, or point me towards some resources that might explain. I don't really understand how `data` is getting down to the `searchThroughData` variable. – Kelderic Oct 12 '14 at 14:52
  • 1
    Sure. You are looking for the concept of a "closure." Here's a stackoverflow link http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – bmavity Oct 12 '14 at 15:02
  • Much appreciated! I'll award the bounty tomorrow after the mandatory wait period is done. – Kelderic Oct 12 '14 at 16:22
  • bmacity, I'm wondering if you might be able to answer a followup question. If I wanted to be able to have `data` change and be live, (not be known before the `addHandler` is run), could I get that to work? Like to use the live variable every time the binding data is changed? – Kelderic Oct 16 '14 at 22:44
  • I've added an update for data being a global variable. If it's not, I will need more information to give you a better answer. – bmavity Oct 19 '14 at 15:35
  • Yeah I ended up having to convert it to a global variable (along with a few others) because doing it the way we had it figured out won't work with a variable that changes after page-load. It's all inside a self-initiating function, though, so the scope isn't too bad. I appreciate the help! – Kelderic Oct 20 '14 at 14:50