Powerpoint Add-In - saveAsync does not save settings when called outside of Office.initialize

别等时光非礼了梦想. 提交于 2019-12-24 18:55:31

问题


I'm developing a content add-in for PowerPoint and I'm trying to persist its state when the user reloads the presentation using the Office.context.document.settings functions (get, set, remove and saveAsync).

However, it appears that saveAsync calls made outside of the Office.initialize function do not actually save the current settings, as upon reloading of the presentation, only the settings saved during the initialization are persisted.

For demonstration, here is a minimal example of a counter initialized at 1 and incremented each time the page is loaded, or when the user clicks an Increment button:

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Counter Add-In</title>

    <!-- Office JavaScript API -->
    <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.debug.js"></script>
</head>

<body>
    <div>
        <h1>Counter Add-In</h1>
        <span id="test-message"></span>
        <button class="ms-Button" id="increment-button">Increment</button>
    </div>

    <script type="text/javascript" src="node_modules/core-js/client/core.js"></script>
    <script type="text/javascript" src="node_modules/jquery/dist/jquery.js"></script>
    <script type="text/javascript" src="app.js"></script>
</body>

</html>

app.js

(function() {

  Office.initialize = function(reason) {
    $(document).ready(function() {
      switch (reason) {
        case 'inserted':
          console.log('The add-in was just inserted.');
          setState('counter', 1);
        case 'documentOpened':
          console.log('The add-in is already part of the document.');
          setState('counter', getState('counter') + 1);
          break;
      }
      $('#test-message').text(getState('counter') || 'NOT FOUND');
      saveState();

      // Callback functions for buttons
      $('#increment-button').click(incrementCounter);
    });
  };

  // Settings/State helpers
  function getState(name) {
    return Office.context.document.settings.get(name);
  }

  function setState(name, val) {
    console.log('Setting', name, 'to', val);
    Office.context.document.settings.set(name, val);
  }

  function saveState() {
    Office.context.document.settings.saveAsync(function(asyncResult) {
      if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
        console.log('Settings saved.');
      } else {
        console.warn('Settings save failed', asyncResult.status, asyncResult.error.message);
      }
    });
  }

  function incrementCounter() {
    var counter = getState('counter');
    setState('counter', counter + 1);
    $('#test-message').text(getState('counter'));
    saveState();
  }

})();

counter-manifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp 
    xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" 
    xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="ContentApp">
    <Id>71a1a0ed-6cd0-4a6e-ad2d-015b8a8b43cb</Id>
    <Version>1.0.0.0</Version>
    <ProviderName>Test</ProviderName>
    <DefaultLocale>en-US</DefaultLocale>
    <DisplayName DefaultValue="DisplayName" />
    <Description DefaultValue="Description"/>
    <IconUrl DefaultValue="https://localhost:3000/assets/icon-32.png" />
    <HighResolutionIconUrl DefaultValue="https://localhost:3000/assets/hi-res-icon.png"/>
    <AppDomains></AppDomains>
    <Hosts>
        <Host Name="Presentation" />
    </Hosts>
    <DefaultSettings>
        <SourceLocation DefaultValue="https://localhost:3000/index.html" />
    </DefaultSettings>
    <Permissions>ReadWriteDocument</Permissions>
    <VersionOverrides 
        xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
        <Hosts>
            <Host xsi:type="Presentation"></Host>
        </Hosts>
        <Resources></Resources>
    </VersionOverrides>
</OfficeApp>

When inserted into a presentation, this add-in first appear to behave correctly (the counter is incremented as expected and Settings saved. is displayed in the console log each time). However when reloading the presentation, and looking at the console log, we can see that the saveAsync call in the incrementCounter has no effect, i.e. the increments from the button clicking are not registered, but the increments from reloading the page are.

Is this a bug or am I missing something?

Edit 2018/01/19

Not sure if you changed something on your end, but today it seems to work perfectly (reloading does not change the counter value)

Edit 2018/05/23

The bug came back again without any change from my end.


回答1:


You need to call refreshAsync prior to attempting to read a given value. This will reach the current settings from the document into memory.

Try this:

function getState(name) {
  Office.context.document.settings.refreshAsync(function(){
     return Office.context.document.settings.get(name);
  });
}


来源:https://stackoverflow.com/questions/48307057/powerpoint-add-in-saveasync-does-not-save-settings-when-called-outside-of-offi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!