问题
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