Angular 5 Excel Office应用:Dialog向Task Pane通信无响应求助
解决Angular 5 Excel插件中Dialog向Task Pane发送消息无回调的问题
我来帮你梳理这个问题——这其实是Angular开发Office插件时非常容易踩的上下文绑定坑,和JQuery多页面场景的差异也源于此。
问题根源:Angular组件方法的this上下文丢失
看你Task Pane里的代码,在callBack方法中直接把this.processMessage传给addEventHandler时,这个方法的this并没有绑定到你的组件实例上。当Office.js触发DialogMessageReceived事件时,this会指向Dialog对象而非你的组件,导致this.message、this.dialog这些组件属性无法访问,看起来就像回调完全没触发一样。
而JQuery多页面场景中,函数的上下文通常是全局作用域或者被正确绑定,所以不会出现这个问题。
解决方案:手动绑定this上下文
有两种常用方式可以解决这个问题,选一种适合你的即可:
方式1:用箭头函数包裹回调(最直观)
修改callBack方法中的事件绑定代码,用箭头函数确保processMessage里的this指向组件:
callBack(result) { this.message = "opened dialog"; this.dialog = result.value; // 用箭头函数包裹,强制绑定组件上下文 this.dialog.addEventHandler(Office.EventType.DialogMessageReceived, (arg) => this.processMessage(arg)); this.message = this.dialog.toString(); }
另外注意:displayDialogAsync的回调this.callBack也需要绑定组件上下文,否则callBack里的this同样会出错,所以openMainWindow里的调用也要调整:
openMainWindow() { this.message = "opening dialog"; Office.context.ui.displayDialogAsync( "https://localhost:3000/#/mainwindow", { height: 100, width: 100 }, this.callBack.bind(this) // 绑定组件上下文 ); }
方式2:在构造函数中提前绑定方法(更优雅)
在组件的构造函数里,提前把需要作为回调的方法绑定到组件实例:
export class TaskPaneComponent { message: string; dialog: Office.Dialog; constructor() { // 提前绑定上下文,后续直接传方法名即可 this.callBack = this.callBack.bind(this); this.processMessage = this.processMessage.bind(this); } openMainWindow() { this.message = "opening dialog"; Office.context.ui.displayDialogAsync( "https://localhost:3000/#/mainwindow", { height: 100, width: 100 }, this.callBack ); } callBack(result) { this.message = "opened dialog"; this.dialog = result.value; this.dialog.addEventHandler(Office.EventType.DialogMessageReceived, this.processMessage); this.message = this.dialog.toString(); } processMessage(arg) { this.message = "received a message from dialog"; this.dialog.close(); this.message = arg.message; } }
额外检查点
除了上下文绑定,还要确认Dialog页面的Office.js是否正确加载:
- 在Dialog页面的
index.html中必须引入Office.js:<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script> - 最好在Dialog组件中等待Office初始化完成后再调用
messageParent:export class MainWindowComponent { message: string; ngOnInit() { Office.initialize = (reason) => { // 初始化完成后再执行相关操作 }; } sendMessage() { this.message = "sending message to parent"; Office.context.ui.messageParent("this is the message from child"); } }
内容的提问来源于stack exchange,提问作者Venkat Rao Vangalapudi
相关产品推荐
相关产品推荐

