关于javascript:注册Office.EventType.ItemChanged时Outlook WebAddin抛出内部服务器错误

Outlook WebAddin throwing internal server error when registering Office.EventType.ItemChanged

在我的 Outlook WebAddin 中,我正在尝试使用以下代码注册邮件 ItemChange 事件。

1
2
3
4
5
    Office.context.mailbox.addHandlerAsync(Office.EventType.ItemChanged, mailItemSelectionChanged, [], function (result) {
            if(result && result.status != 'succeeded'){
                console.error('result => ' + result);
             }
});

每当用户在固定模式下更改邮件时,我都会第一次收到邮件更改事件。然后,如果对话发生变化,我将使用 location.reload() 重新加载插件以清除缓存并重新加载插件。

重新加载插件后,无法注册mailItemChange事件并抛出以下错误:

{"code": 5001,"message":"An internal error has occurred.","name":
"Internal Error"}

它在浏览器和一些 Windows 机器中失败(在许多其他情况下工作)。

前景诊断:

{"host":"Outlook","platform":"OfficeOnline","version":
"16.0.9215.1000"}


关于 Office.EventType.ItemChanged 事件注册,我可以找出以下行为:

  • 您不能注册多个事件处理程序。大多数人在第二次尝试注册事件处理程序时都会出错,因此第一个事件处理程序没有被取消注册。
  • 事件处理程序的注册超出加载项网页的生命周期。这意味着,当您的加载项卸载当前网页并重新加载相同或不同的网页(即导航到另一个网页)时,您的事件处理程序的注册仍将保留。
  • 在注销事件处理程序时,您不仅必须提供处理程序函数的名称,而且还要确保该函数与您用于注册事件的函数完全相同。换句话说,如果您在重新加载网页后尝试注销事件处理程序,则处理程序函数的对象不一样,因此事件处理程序不会被注销。
  • 当 Outlook 关闭加载项窗格时,事件处理程序注册将丢失。
  • 因此,在您的情况下,您需要在调用 location.reload() 之前取消注册事件,如下所示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Office.context.mailbox.removeHandlerAsync(Office.EventType.ItemChanged, {handler: mailItemSelectionChanged}, function(result) {
        if (result.status === Office.AsyncResultStatus.Failed) {
            console.log('Item Change event could not be unregistered.');
            console.log(result.error);
        }
        else {
            console.log('Item Change event unregistered successfully.');
        }
    });
    setTimeout(function() {location.reload();}, 100);

    那些想从他们的插件导航到相同或另一个网页的人,他们可以将点击事件处理程序附加到锚标记(或按钮),以确保 ItemChanged 事件处理程序在当前事件处理程序之前已被取消注册页面已卸载。我已使用以下代码完成此操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $(document).ready(function() {
        $('.NavBarContainer a').toArray().forEach(function(anchor1, index) {
            $(anchor1).click(function(event) {
                if(itemChangeEventRegistered) {
                    unregisterItemChangeHandler();
                    setTimeout(function() {window.location = anchor1.href;}, 100);
                    return false;
                }
                return true;
            });
        });
    });