Excel SelectionChanged事件未触发

时间:2018-02-24 02:05:38

标签: javascript excel reactjs office-js

开发链:Microsoft Visual Studio代码,Excel在线插件,使用Chrome调试

我一直在开发一个Excel加载项,使用上述工具已经有一段时间了。最近,我遇到了在运行调试版本时没有触发Excel SelectionChanged事件的问题,尽管成功调用(和异步回调)到AddHandlerAsync。实际上只有十分之一的呼叫会成功设置挂钩。

我的代码中没有改变任何主要内容,但我的组织最近在所有设备上实施了MDM,包括台式机和笔记本电脑。正如您可能想象的那样,这对我的工作效率构成了巨大的障碍。

我使用的是React(create-react-app)和office-ui-fabric-react

我有以下代码来设置回调:

window.addEventListener('DOMContentLoaded', () => {
    Office.initialize = (reason) => {
        console.log('Office.initialize called with reason = ' + reason)

        Office.context.document.addHandlerAsync(
            Office.EventType.DocumentSelectionChanged,
            (eventArgs) => {
                this.onExcelSelectionChanged(eventArgs)
            },
            (asyncResult) => {
                if (asyncResult.status == "succeeded") {
                    console.log('Selection changed handler was added')
                } else {
                    console.log(`Error setting event: ${JSON.stringify(asyncResult)}`);
                }
            })
    }
})

调用成功,但在VS Code调试器(使用Debugger for Chrome扩展程序)中运行时,事件不会触发。以前工作正常。它似乎在生产环境中运行良好。

编辑2/23/2018:

我似乎在很大程度上解决了我的问题。我正在使用React Router,并为每个路径设置了Office.initialize个函数。

在尝试解决问题时,我使用create-react-app创建了一个全新的加载项,如Build an Excel add-in using React中所述。我注意到Office.initialize位于index.js,包含ReactDOM.render(...)电话。我在我的代码中重新调整了一些东西以模仿这个,现在它似乎工作得更好,虽然它偶尔也会错过钩子。

2 个答案:

答案 0 :(得分:1)

说到Office.t initialize,最重要的规则是尽早分配你的功能 。在您分配Office.initialize之前,Office无法连接您的加载项,如果耗时过长,它可能会非常积极地进行超时(平台之间的差异为5秒{{3} }})。

如果没有看到你如何站起来react-router,很难确切知道发生了什么。也就是说,您的index.js看起来应该是这样的:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
import { BrowserRouter } from "react-router-dom";

const Office = window.Office;

Office.initialize = (reason) => {
  ReactDOM.render(
    <BrowserRouter>
      <App />
    </BrowserRouter>,
    document.getElementById("root")
  );
  registerServiceWorker();
};

请注意,这不包含在window.addEventListener('DOMContentLoaded', () => {}中。这很重要,因为等待DOMContentLoaded意味着您在分配Office.initialize之前等待太长。相反,我们会在联系reactreact-router-dom之前将Office连接起来。

如果您想等待DOM加载,您可以在初始化函数中执行此操作:

Office.initialize = reason => {
  window.addEventListener("DOMContentLoaded", () => {
    ReactDOM.render(
      <BrowserRouter>
        <App />
      </BrowserRouter>,
      document.getElementById("root")
    );
    registerServiceWorker();
  });
};

话虽如此,我自己也从未遇到过需要。我建议最初放弃DOMContentLoaded。如果您发现特定需要,可以随时添加它。

答案 1 :(得分:0)

很抱歉给您带来不便。您是否在在线版和桌面版上都遇到了问题?

another issue正在调查中。您可以与我们分享任何调试信息吗?