为什么 Outlook 的 RoamingSettings 对象在页面重新加载/重定向后用旧值初始化?

Why Outlook's RoamingSettings object initialized with old values after page re-load/ redirect?

前提条件:

编码:

// The Office initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
    $(document).ready(function () {
        app.initialize();

         var settings = Office.context.roamingSettings;

        // Get the current value of the 'myKey' setting
        // let's assume it was set and stored with value "Hello World!" previously
        var value = settings.get('myKey');

        // Update the value of the 'myKey' setting
        settings.set('myKey', 'Reload World!');

        // Persist the change
        settings.saveAsync();

        var $btn_reload = $('#btnReload');
        $btn_reload.off('click').on('click', reloadThePage);
    });
};
function reloadThePage() {
    // re-load current page
    window.location.href = self.location.href;
};

工作流程:

通过代码我们对 value 变量感兴趣。第一次加载我们假设 "value" 设置为 "Hello World!"。页面加载后,该值将设置为 "Reload World!" 并将保存到服务器邮箱。单击 HTML 按钮后将触发简单的页面重新加载。代码将再次开始执行整个序列。根据 Office.initialize 之后的文档,我们的 "roamingSettings" 对象已准备好使用,我们再次检查 "value"。我希望这个值是 "reload World!",但我得到的是旧值 "Hello World!"。

当代码导航到另一个页面时,会发生同样的情况。此页面将类似,在 Office.initialize "roamingSettings" 之后仍将保留 值 "Helllo World!" 而不是保存新值 "Reload World!".

请注意,我们用 "saveAsync" 存储到服务器的值确实发生了变化。这很容易验证。 运行 相同的场景,关闭加载项(加载项 iframe)后重新打开。页面初始加载时的 "value" 将是正确的 "Reload World!"。

结论(我对这个问题的推测):

调试问题时,我注意到 Office.context.roamingSettings 持有两个不同的私有对象:一个名为 "settings...",第二个名为 "rawSettings..."。在初始加载时 "rawSetting..." 将保留所有设置,而 "Settings..." 将不存在。在第一次访问特定设置键后,"Settings..." 对象创建并且 "RawSettings..." 将被设置为空。使用设置时,您实际上使用的是 "Settings..."。重新加载/重定向后 "RawSettings..." 再次出现,但它将保留未更新的旧数据。同时,如果您完全关闭加载项并再次打开它,"rawSettings..." 将保留新的更新数据。

这让我觉得加载项的 iFrame 在某处保存相同的数据,用于在加载时重新初始化 "in-memory" 对象。在加载项启动期间,此数据将从邮箱中提取,但当您重新加载页面或重定向到应用程序的另一个页面时,将使用来自 iFrame 的数据,并且它不是最新的。

有人能澄清一下它是不是这样设计的吗?我是不是用错了对象?

请注意,对于使用单页应用且不需要重新加载任何页面的加载项,这不是问题。当由于某种原因加载项需要重新加载整个页面(例如从头开始重新初始化所有内容)或使用多页面应用程序时,就会出现这种情况。

这是一个已知问题,在积压中。我们目前没有要分享的预计到达时间。

我已经为这个问题创建了一个解决方法。这是 link 我的博客 post 关于它的文章:

http://metrosharesolutions.com/blogs/office365development/roaming-settings-workaround/

这是我的代码 link:

https://github.com/joeparzel/RoamingFix

此变通办法会在某种程度上禁用自定义属性功能,但它可以解决那些正在创建单页纸的人的问题。这是博客 post:

的摘录

In order to accomplish this workaround, we’ve added some extra (parsable) information to the Value that is saved with the Key – specifically we add a GUID and a date/time stamp. After appending this extra information to the value, we save the value to both Roaming Settings and Custom Properties. This is done because of the “reload” issue described in the Stack Overflow post referenced earlier. Finally, we don’t really remove values from the Roaming Settings / Custom Properties databases; rather we set the values to what our code thinks means “deleted.” To retrieve the correct value, the code will decipher which value (between Roaming Settings and Custom Properties) is correct based on the date/time stamp and return the GUID if the key has been deleted.

此解决方法的代码受 MIT 许可,因此请随意下载并将其添加到您自己的生产 Outlook 加载项中……当然要经过测试!

根据文档,保存的值可以在下次使用插件时检索,无论如何我们需要在保存后直接检索值时重新加载插件。我想这是一个可以接受的解决方法。