如何在Office.js Excel事件处理程序中包装可观察的对象

时间:2019-07-08 19:04:09

标签: excel angular typescript promise office-js

在Office.js(特别是Excel)中,您可以添加/注册事件处理程序(技术上是Promises)。因此,例如,Microsoft的文档提供了以下示例:

await Excel.run(async (context) => {
    let sheet = context.workbook.worksheets;
    sheet.onAdded.add(onWorksheetAdd);

    await context.sync();
    console.log("A handler has been registered for the OnAdded event.");
});

尽管我目前正在Angular工作,所以我想将所有这些async代码“纠缠”到observable中,以便对Excel文档上发生的一切有一定的控制感。在上面的示例中,我们正在侦听用户添加新工作表的时间。 onWorksheetAdd将注册该事件处理程序,以便当用户执行操作(添加新工作表)时,将调用onWorksheetAdd回调/承诺。

以下是我目前所拥有的。

excel-worksheet.service.ts

registerOnAddWorksheetHandler() {
        return from(
            // @ts-ignore
            Excel.run((context) => {
                    let sheet = context.workbook.worksheets;
                    sheet.onAdded.add(this.excelEventHandlerService.onAddWorksheetHandler) ; // must pass Promise as argument

                    console.log("A handler has been registered for the OnAdded event.");
                }
                return context.sync();
            })
        );
    }

excel-event-handler.service.ts

 onAddWorksheetHandler(event): Promise<any> {
        return of(
            // @ts-ignore
            Excel.run((context) => {
                    console.log("Handler for worksheet onAdded event has been triggered. Newly added worksheet Id : " + event.worksheetId, event);

                return context.sync();
            })
        )
        .toPromise()
    }

本质上,我想要的是将事件处理程序包装在Observable中,以便我的app.component.ts可以将信息注册到我的应用程序中。

我尝试了以下方法:

  • onAddWorksheetHandler中,我试图继续解决承诺。这样,我在.then()之后调用了context.sync(),然后在Excel.run()上再次调用了它,然后在toPromise()之后调用了它。不过,这是不成功的,因为registerOnAddWorksheetHandler已注册了该事件,并且无法访问该事件的值。主要是因为Office.js基于Promise,所以执行是一劳永逸的。
  • 我尝试在Subject上声明excel-event-handler.service.ts,以便app.component.ts可以访问,但是也失败了。我不确定注册的事件处理程序是否正在吞下任何试图冒泡的东西。

我要尝试解决的最后一件事就是将那些已注册的事件处理程序移至app.component.ts才能访问范围。我希望能做得更好一些。

1 个答案:

答案 0 :(得分:0)

这对我来说是一个误会。对于office.js事件处理程序,只需要执行Excel.run()context.sync()命令即可​​实际上只注册<some_callback()>

Excel.run((context) => {
  let sheet = context.workbook.worksheets;
  sheet.onAdded.add(<some_callback()>);
  return context.sync();
})

我感到困惑的是,我认为整个Excel.run()舞蹈都必须在<some_callback()>内执行。事实并非如此,您可以将其作为典型的JS回调。在Angular中,可以是组件中需要执行的任何方法。相同的逻辑适用于任何其他框架。

我希望这对其他人有帮助。