【发布时间】:2019-07-25 21:10:01
【问题描述】:
我正在使用 Javascript 开发 Excel 插件。我遇到了一些非常奇怪的行为,所以我主要关心是否必须使用 context.trackedObjects.add() 。我的代码的一般流程是...
- 从用户那里获取一系列数据。 使用 Excel.run #1。
- 使用简单的 AJAX 调用调用 Azure 函数来计算一些统计信息。 使用 Excel.run #2
- 使用 TypeScript 类中的代码编写结果。 从第 2 步接收上下文
代码放在这里太长了,这是一个总结版本。请注意,在第一个 Excel.run 中引用上下文的所有对象都不会在第二个 Excel.run 中使用。传递给该类的唯一变量是 Excel 上下文和 JSON 字符串。
function UserClicksButton() {
await Excel.run(async (ctx) => { **//Excel.run #1**
let MyData:string = await GetDataFromSheet(ctx); //step 1, get stringified JSON object
GetStatsFromServer(MyData,ReturnObject); //step 2
}
}
async function GetStatsFromServer(In_Data,Return_Object) {
var settings = {
"async": true,
"crossDomain": true,
//others removved
},
"data": In_Data
}
$.ajax(settings).done(function(response) {
Excel.run(async (ctx) => { **//Excel.run #2**
let myChart= new MyChart();
myChart.CreateChart(ctx, response);
});
}).
.fail {//deal with fail}
}
class MyChart {
m_ctx:Excel.RequestContext;
m_AnswerString: String;
public async CreateChart(ctx: Excel.RequestContext, AnswerString:string) {
this.m_ctx=ctx;
this.m_AnswerString = AnswerString;
//create chart using this.m_ctx
//Excel.run is not called in class at all
}
}
我问的原因是我遇到了一些非常奇怪的错误。在某一时刻,我得到“对象路径 Chart.add 不适用于您要执行的操作。如果您在多个 \"context.sync\" 调用中使用该对象,并且在顺序执行之外".run\" 批处理,请使用 \"context.trackedObjects.add()\" 和 \"context.trackedObjects.remove()\" 方法来管理对象的生命周期。"
但是,根据我输入“await this.m_ctx.sync()”的位置,我会收到不同的错误或根本没有错误。例如,MyChart 类中的 CreateChart 函数相当长,因为它对图表进行了大量的格式化。它可以缩写为(为简洁起见省略变量声明)...
class MyChart {
m_ctx:Excel.RequestContext;
m_AnswerString: String;
public async CreateChart(ctx: Excel.RequestContext, AnswerString:string) {
this.m_ctx=ctx;
this.m_AnswerString = AnswerString;
//create chart using this.m_ctx
newChart= sheet.charts.add("XYScatter", dataRange, "Auto");
formatTitle(newChart);
await this.formatAxis(newChart);
//await this.m_ctx.sync(); //TODO: remove when done debugging
await this.formatSeries0(newChart);
//await this.m_ctx.sync(); //TODO: remove when done debugging
await this.formatSeries1(newChart);
//await this.m_ctx.sync(); //TODO: remove when done debugging
await this.formatSeries2(newChart);
//await this.m_ctx.sync(); //TODO: remove when done debugging
await this.formatSeries3(newChart);
//await this.m_ctx.sync(); //TODO: remove when done debugging
await this.formatSeries4(newChart);
}
}
注释掉的行“await this.m_ctx.sync();”我添加以查找有问题的代码行。但是,它会改变代码的行为。使用 await() 函数,我没有收到错误消息。随着等待,我有时会得到一个错误。
一些笔记。图表的创建都是“输出”。我没有从 Excel 上下文中加载任何内容。它是 100% 写入工作表的。我真的不需要函数是异步的,我只是让它们aysnc 能够调用await ctx.sync()。
在寻找问题的过程中,我发现这篇文章似乎并不适用,因为我没有在多个上下文之间共享变量。
Word Online Add-In: Using objects across multiple contexts
我知道我可以让函数 GetStatsFromServer 返回一个承诺,但根据 Zlatkovsky 的书,保持与 IE 的兼容性将其限制为 Excel 1.2 API,使用 Q 库(无法在我的 PC 上加载),或者获取进入我现在头顶的promise polyfill。虽然让这个函数返回一个 promise 会更干净,但现在我专注于这个问题,因为我的理解是它应该以这种方式工作。
【问题讨论】:
-
重新。 “保持与 IE 的兼容性将其限制为 Excel 1.2 API”:事实并非如此。如果我的书中有什么地方让您产生了这种印象,请告诉我,以便我更正它!对于 Promise 的 polyfill,最简单的 polyfill 就是包含类似
window.Promise = Office.Promise这样的行,它可以满足您的需要。 -
第 73 页,第 4.3.2 节列出了实现承诺的三种方法。我很确定我的帖子完全按照您的书的顺序列出了它们,即 OfficeExtension.Promise,它需要 ExcelAPI 1.2、Q 库和 promise polyfil。但是,除此之外,对我的问题的回答会更有帮助。 stackoverflow 的 Office-js 部分是一座鬼城。如果微软的人不回答这些问题,那么他们就不会得到回答。验证清单的系统似乎完全崩溃了。我已经发布了多个潜在的错误,但没有回复。
-
我明白了。好的,就
OfficeExtension.Promise而言,这是有道理的,我将更新该部分。它经过更改和简化,因此现在如果您使用window.Promise = Office.Promise(注意:Office而不是OfficeExtension),您甚至可以使用旧版本。
标签: office-js