如何使用Angular的Office JS中的addHandlerAsync

时间:2017-06-12 22:59:28

标签: angular office-js

我正在使用Angular创建一个Excel加载项,并为各种单元格创建了绑定。我有一个表单,显示这些绑定单元格中的数据,我希望表单在单元格中的数据更改时更新。在OfficeJS库中,它使用:

引用
addHandlerAsync(Office.EventType.BindingDataChanged, <handler method>)

https://dev.office.com/reference/add-ins/shared/binding.addhandlerasync

但是,当我尝试在Angular组件或服务中的TS中执行此操作时,处理程序在触发时无法从组件或服务调用任何方法。它只能在处理程序中运行Office JS方法。我该怎么做才能从处理程序中触发组件或服务方法?

用例的一个示例是,如果您希望每次在电子表格中的任何单元格绑定中发生更改时触发加载项中的内容,例如在加载项中显示某些内容。这似乎是一种支持的一般操作。文档在JS中显示了类似的内容:

function addHandler() {
Office.select("bindings#MyBinding").addHandlerAsync(
    Office.EventType.BindingDataChanged, dataChanged);
}
function dataChanged(eventArgs) {
    write('Bound data changed in binding: ' + eventArgs.binding.id);
}
// Function that writes to a div with id='message' on the page.
function write(message){
    document.getElementById('message').innerText += message; 
}

然而,当我尝试做类似的事情时:

 createHandlerOnA1(): Promise<IOfficeResult> {
        return new Promise((resolve, reject) => {
            this.workbook.bindings.getByIdAsync(this.bindingName, (result: Office.AsyncResult) => {
                if(result.status === Office.AsyncResultStatus.Failed) {
                    reject({
                        error: 'failed to get binding by id'
                    });
                } else {
                    result.value.addHandlerAsync(Office.EventType.BindingDataChanged, this.changeEvent, (handlerResult: Office.AsyncResult) => {
                        if(handlerResult.status === Office.AsyncResultStatus.Failed) {
                            reject({
                                error: 'failed to set a handler'
                            });
                        } else {
                            // Successful 
                            resolve({
                                success: 'successfully set handler'
                            });
                        }
                    })
                }
            })
        })
    }

  addHandler() {
    this.createHandlerOnA1()
    .then((result: any) => {
      this.feedback = result.success;
    }, (result: IOfficeResult) => {
      this.feedback = result.error;
    });
  }

  changeFeedback() {
    this.feedback = 'hello'
  }

  // Excel methods
  changeEvent(eventArgs: any) {
      Excel.run(async (context) => {
            const data = [
                ["Hello World"]
            ];
      const range = context.workbook.getSelectedRange()
      range.values = data;
      await context.sync();
    });
    // Handler cannot run this
    // this.changeFeedback(); 
  }

函数changeFeedback()无法在changeEvent(eventArgs:any)处理程序中运行。我在这里做了一个示例回购以证明问题:

https://github.com/brandonkoch6/addHandlerAsyncError

我试图更改对处理程序的引用,以便它保持&#39;这个&#39;通过这样做:

addHandlerAsync(Office.EventType.BindingDataChanged, (eventArgs:any) => this.changeEvent(eventArgs))

addHandlerAsync(Office.EventType.BindingDataChanged, this.changeEvent.bind(this))

那些不解决它的人。所以,我有点不知所措。

任何帮助将不胜感激。我认为它与上下文对象有关,这个&#39;当处理程序运行时。添加处理程序时有一个[options]参数,但我似乎无法找到文档中提供的所有选项:

https://dev.office.com/docs/add-ins/develop/asynchronous-programming-in-office-add-ins#passing-optional-parameters-to-asynchronous-methods

1 个答案:

答案 0 :(得分:1)

问题是因为代码用完了角区。

您需要让代码在区域内运行。检查my codethis article以了解其工作原理。

import { NgZone } from '@angular/core';

// ...

constructor(private zone: NgZone) { }

myFunction() {
  this.zone.run(() => {
    // the code
  });
}

P.S。我创建了一个问题here。我有空的时候会尽快更新文件。