【问题标题】:Office-js Excel addin : when to return context.sync()Office-js Excel 插件:何时返回 context.sync()
【发布时间】:2019-01-27 12:26:16
【问题描述】:

我很难理解何时使用context.sync()

这是一个基本的例子,但它恢复了我的理解:

Excel.run(function (context){
    const wb = context.workbook;
    const ws = wb.worksheets.getActiveWorksheet();

    // should never happened, but is it correct to check like this ?
    if (wb === null) {
        // IS IT CORRECT TO DO THIS ?
        // I just want to exit the function
        // return; would be enough ? What's going on in the callstack?
        return context.sync();
    }
    ws.load("name");
    return context.sync().then(function() {
        var name = wb.name;
        // do stuff
        var range = ws.getRangeByIndexes(1,1,10,10);
        return context.sync().then(function() {
             ws.names.add("NEWRANGE", range);
             // mandatory return context.sync() to refresh Excel object ?
             // doesn't work otherwise for me
             return context.sync();
        });
    }
}).catch(function(error) {
  // do stuff
}

如果有人能解释一下,那就太受欢迎了:)

干杯。

【问题讨论】:

  • 我推荐这本电子书:leanpub.com/buildingofficeaddins,其中开发 JS API 的 MS 团队成员 Michael Zlatkovsky 解释了这一点。 FWIW 最后一个 context.sync 调用是绝对不是必要的。第二个是。首先:对于您向我们展示的内容不是必需的,但这取决于if 中发生的事情。
  • 据我了解,我需要使用 context.sync() 是我需要与 Excel 交互,例如 ws.names.add("new_range", range)。我将修改示例以使其更清晰。
  • 示例修改为添加新的范围名称。
  • 当您需要来自 Excel 的信息以便在代码中使用它时,您需要使用 context.sync。在您的示例中,您在 Excel 中“查询”某些内容的唯一时间是 name 属性,因此您加载该属性然后需要同步。真的,如果你读过这本书但仍然不确定,最好的方法就是尝试一下。
  • @Val 请使用 Script Lab 工具 (appsource.microsoft.com/en-us/product/office/…) 确保您至少获得了形式上正确的代码。您至少有一个缺少右括号。您加载了工作表的名称,但随后您尝试读取 工作簿 的名称。如果 wb 为 null,则第 3 行将引发错误,因此永远不会达到您的 if 条件。

标签: javascript excel office-js office-addins office365-apps


【解决方案1】:

我认为将这些对象视为代理对象会有所帮助。它们只是真实对象的表示,并非所有属性都可以在代理对象上使用,因为它们不需要可用。同样,对代理对象所做的更改不会更新真实对象。 context.sync() 用于将代理对象与真实对象同步。

查看您的代码,第一个 context.sync() 是不必要的,因为您不需要检索任何内容或进行任何更改。实际上整个条件if (wb === null) 是不必要的,因为 context.workbook 不能为空。

当您尝试ws.load("name"); 时,您需要一个 context.sync(),因为您尝试访问需要从真实对象加载的代理对象上的属性。

当您调用var range = ws.getRangeByIndexes(1,1,10,10); 时,您不需要 context.sync(),因为您只是在抓取另一个代理对象,但没有进行任何更改,也没有访问任何属性。

但是由于ws.names.add("NEWRANGE", range); 是一个真正的变化,你需要一个 context.sync() 来反映真实对象的变化。从技术上讲,最后一个 context.sync() 不是必需的,因为 Excel.run 在运行 Excel.run() 中的所有内容后实际上会调用 context.sync()。也就是说,无论如何最好有一个结束 context.sync()。

您还可以在一个 context.sync() 中批处理独立的操作。由于var range = ws.getRangeByIndexes(1,1,10,10);ws.names.add("NEWRANGE", range); 无关,您实际上可以将它们放在单个context.sync() 后面。

我还建议改用 TypeScript,以使您的代码更简洁、更易于理解。尝试在 Excel 中使用 ScriptLab。有很多示例可以帮助您总体理解 context.sync() 和 office-js。

最后,这是您可以编写的执行相同操作的代码。

Excel.run(function (context) {
    const wb = context.workbook;
    const ws = wb.worksheets.getActiveWorksheet();

    ws.load("name");
    return context.sync().then(function () {
        var name = wb.name;
        // do stuff
        var range = ws.getRangeByIndexes(1, 1, 10, 10);
        ws.names.add("NEWRANGE", range);
        return context.sync();
    });
}).catch(function (error) {
    // do stuff
});

哦,你应该按照 Cindy 的建议看看 Michael 的书。

【讨论】:

  • 感谢您的清晰解释。代理对象就是答案;)!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多