綁定對象(字)工作word.run沒有在服務器環境
網址:https://dev.office.com/reference/add-ins/shared/bindings.bindings
創建綁定變量:
- 使用Office.context.document.getSelectedDataAsync (),使用 Office.context.document.bindings.addFromSelectionAsync()向當前選擇添加一個TextBinding asyncResult.value(響應)
填充內容
- 使用Binding.setDataAsync方法我們將數據寫入到由指定的綁定對象所表示的文檔的結合部。 現在的問題是我們無法設置{coercionType:「html」}在文檔的裝訂部分插入富文本,它可以與文本一起工作。
問題:
- 無法在網上字插入使用setDataAsync()富文本
- 無法讓使用bindingId內容的主動式選擇,這將幫助我們使用Office .context.document.setSelectedDataAsync()將數據寫入文檔中的當前選區(Rich text可與此API協同工作)。我們需要在使用此方法之前釋放綁定。
- 無法通過將函數傳遞給Office.initialize後的Word.run()方法來執行 Word.run(function(context){});
沒有控制檯錯誤或警告,但當試圖通過服務器執行代碼時,Word.run()塊永遠不會運行。本地開發環境適用於這種情況。
清單
<?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="TaskPaneApp">
<!-- BeginBasicSettings: Add-in metadata, used for all versions of Office unless override provided -->
<!--IMPORTANT! Id must be unique for your add-in, if you clone this manifest ensure that you change this id to your own GUID -->
<Id>010861c8-0558-472c-b350-f7795e27cfa5</Id>
<!--Version. Updates from the store only get triggered if there is a version change -->
<Version>1.0.0.0</Version>
<ProviderName>Parrot365 : [QA]</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<!-- The display name of your add-in. Used on the store and various placed of the Office UI such as the add-ins dialog -->
<DisplayName DefaultValue="Parrot365 : [QA]" />
<Description DefaultValue="Parrot365 : QA Mode"/>
<!--Icon for your add-in. Used on installation screens and the add-ins dialog -->
<IconUrl DefaultValue="https://qaparrot365.wittyparrot.com/resources/assets/images/wp_logo_32px.png" />
<HighResolutionIconUrl DefaultValue="https://qaparrot365.wittyparrot.com/resources/assets/images/wp_logo_128px.png" />
<SupportUrl DefaultValue="http://support.wittyparrot.com/support/home" />
<!--BeginTaskpaneMode integration. Office 2013 and any client that doesn't understand commands will use this section.
This section will also be used if there are no VersionOverrides -->
<Hosts>
<Host Name="Document" />
<Host Name="Workbook" />
<Host Name="Presentation" />
</Hosts>
<DefaultSettings>
<SourceLocation DefaultValue="https://qaparrot365.wittyparrot.com?source=msoffice" />
</DefaultSettings>
<!--EndTaskpaneMode integration -->
<Permissions>ReadWriteDocument</Permissions>
<!--BeginAddinCommandsMode integration-->
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
<!-- Optional, override the description of the Add-in -->
<Description resid="residToolTip" />
<!--Required, hosts node. Each host can have a different set of commands -->
<Hosts>
<!--Specific host. Workbook=Excel, Document=Word, Presentation=PowerPoint -->
<Host xsi:type="Document">
<!-- Form factor. Currenly only DesktopFormFactor is supported. We will add TabletFormFactor and PhoneFormFactor in the future-->
<DesktopFormFactor>
<!--GetStarted information used on the callout that appears when installing the add-in.
Ensure you have build 16.0.6769 or above for GetStarted section to work-->
<GetStarted>
<!--Title of the Getting Started callout. resid points to a ShortString resource -->
<Title resid="Witty.GetStarted.Title"/>
<!--Description of the Getting Started callout. resid points to a LongString resource -->
<Description resid="Witty.GetStarted.Description"/>
<!--Not used right now but you need to provide a valid resource. We will add code in the future to consume this URL.
resid points to a Url resource -->
<LearnMoreUrl resid="Witty.GetStarted.LearnMoreUrl"/>
</GetStarted>
<FunctionFile resid="residDesktopFuncUrl" />
<!--PrimaryCommandSurface==Main Office Ribbon-->
<ExtensionPoint xsi:type="PrimaryCommandSurface">
<OfficeTab id="TabHome">
<!--Group. Ensure you provide a unique id. Recommendation for any IDs is to namespace using your companyname-->
<Group id="Witty.Citations.Group1Id1">
<!--Label for your group. resid must point to a ShortString resource -->
<Label resid="residLabel4" />
<!--Icons. Required sizes 16,31,80, optional 20, 24, 40, 48, 64. Strongly recommended to provide all sizes for great UX -->
<!--Use PNG icons and remember that all URLs on the resources section must use HTTPS -->
<Icon>
<bt:Image size="16" resid="icon1_16x16" />
<bt:Image size="32" resid="icon1_32x32" />
<bt:Image size="80" resid="icon1_80x80" />
</Icon>
<!--Control. It can be of type "Button" or "Menu" -->
<Control xsi:type="Button" id="Button3Id1">
<!--Label for your button. resid must point to a ShortString resource -->
<Label resid="residLabel3" />
<Supertip>
<!--ToolTip title. resid must point to a ShortString resource -->
<Title resid="residLabel" />
<!--ToolTip description. resid must point to a LongString resource -->
<Description resid="residToolTip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="icon1_16x16" />
<bt:Image size="32" resid="icon3_32x32" />
<bt:Image size="80" resid="icon1_80x80" />
</Icon>
<!--This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFuncion or ShowTaskpane-->
<Action xsi:type="ShowTaskpane">
<!--Provide a url resource id for the location that will be displayed on the taskpane -->
<SourceLocation resid="residUnitConverterUrl" />
</Action>
</Control>
</Group>
</OfficeTab>
</ExtensionPoint>
</DesktopFormFactor>
</Host>
<Host xsi:type="Workbook">
<!-- Form factor. Currenly only DesktopFormFactor is supported. We will add TabletFormFactor and PhoneFormFactor in the future-->
<DesktopFormFactor>
<!--GetStarted information used on the callout that appears when installing the add-in.
Ensure you have build 16.0.6769 or above for GetStarted section to work-->
<GetStarted>
<!--Title of the Getting Started callout. resid points to a ShortString resource -->
<Title resid="Witty.GetStarted.Title"/>
<!--Description of the Getting Started callout. resid points to a LongString resource -->
<Description resid="Witty.GetStarted.Description"/>
<!--Not used right now but you need to provide a valid resource. We will add code in the future to consume this URL.
resid points to a Url resource -->
<LearnMoreUrl resid="Witty.GetStarted.LearnMoreUrl"/>
</GetStarted>
<FunctionFile resid="residDesktopFuncUrl" />
<!--PrimaryCommandSurface==Main Office Ribbon-->
<ExtensionPoint xsi:type="PrimaryCommandSurface">
<OfficeTab id="TabHome">
<!--Group. Ensure you provide a unique id. Recommendation for any IDs is to namespace using your companyname-->
<Group id="Witty.Citations.Group1Id1">
<!--Label for your group. resid must point to a ShortString resource -->
<Label resid="residLabel4" />
<!--Icons. Required sizes 16,31,80, optional 20, 24, 40, 48, 64. Strongly recommended to provide all sizes for great UX -->
<!--Use PNG icons and remember that all URLs on the resources section must use HTTPS -->
<Icon>
<bt:Image size="16" resid="icon1_16x16" />
<bt:Image size="32" resid="icon1_32x32" />
<bt:Image size="80" resid="icon1_80x80" />
</Icon>
<!--Control. It can be of type "Button" or "Menu" -->
<Control xsi:type="Button" id="Button3Id1">
<!--Label for your button. resid must point to a ShortString resource -->
<Label resid="residLabel3" />
<Supertip>
<!--ToolTip title. resid must point to a ShortString resource -->
<Title resid="residLabel" />
<!--ToolTip description. resid must point to a LongString resource -->
<Description resid="residToolTip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="icon1_16x16" />
<bt:Image size="32" resid="icon3_32x32" />
<bt:Image size="80" resid="icon1_80x80" />
</Icon>
<!--This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFuncion or ShowTaskpane-->
<Action xsi:type="ShowTaskpane">
<!--Provide a url resource id for the location that will be displayed on the taskpane -->
<SourceLocation resid="residUnitConverterUrl" />
</Action>
</Control>
</Group>
</OfficeTab>
</ExtensionPoint>
</DesktopFormFactor>
</Host>
<Host xsi:type="Presentation">
<!-- Form factor. Currenly only DesktopFormFactor is supported. We will add TabletFormFactor and PhoneFormFactor in the future-->
<DesktopFormFactor>
<!--GetStarted information used on the callout that appears when installing the add-in.
Ensure you have build 16.0.6769 or above for GetStarted section to work-->
<GetStarted>
<!--Title of the Getting Started callout. resid points to a ShortString resource -->
<Title resid="Witty.GetStarted.Title"/>
<!--Description of the Getting Started callout. resid points to a LongString resource -->
<Description resid="Witty.GetStarted.Description"/>
<!--Not used right now but you need to provide a valid resource. We will add code in the future to consume this URL.
resid points to a Url resource -->
<LearnMoreUrl resid="Witty.GetStarted.LearnMoreUrl"/>
</GetStarted>
<FunctionFile resid="residDesktopFuncUrl" />
<!--PrimaryCommandSurface==Main Office Ribbon-->
<ExtensionPoint xsi:type="PrimaryCommandSurface">
<OfficeTab id="TabHome">
<!--Group. Ensure you provide a unique id. Recommendation for any IDs is to namespace using your companyname-->
<Group id="Witty.Citations.Group1Id1">
<!--Label for your group. resid must point to a ShortString resource -->
<Label resid="residLabel4" />
<!--Icons. Required sizes 16,31,80, optional 20, 24, 40, 48, 64. Strongly recommended to provide all sizes for great UX -->
<!--Use PNG icons and remember that all URLs on the resources section must use HTTPS -->
<Icon>
<bt:Image size="16" resid="icon1_16x16" />
<bt:Image size="32" resid="icon1_32x32" />
<bt:Image size="80" resid="icon1_80x80" />
</Icon>
<!--Control. It can be of type "Button" or "Menu" -->
<Control xsi:type="Button" id="Button3Id1">
<!--Label for your button. resid must point to a ShortString resource -->
<Label resid="residLabel3" />
<Supertip>
<!--ToolTip title. resid must point to a ShortString resource -->
<Title resid="residLabel" />
<!--ToolTip description. resid must point to a LongString resource -->
<Description resid="residToolTip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="icon1_16x16" />
<bt:Image size="32" resid="icon3_32x32" />
<bt:Image size="80" resid="icon1_80x80" />
</Icon>
<!--This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFuncion or ShowTaskpane-->
<Action xsi:type="ShowTaskpane">
<!--Provide a url resource id for the location that will be displayed on the taskpane -->
<SourceLocation resid="residUnitConverterUrl" />
</Action>
</Control>
</Group>
</OfficeTab>
</ExtensionPoint>
</DesktopFormFactor>
</Host>
</Hosts>
<Resources>
<bt:Images>
<bt:Image id="icon1_16x16" DefaultValue="https://qaparrot365.wittyparrot.com/resources/assets/images/widget_logo.png">
</bt:Image>
<bt:Image id="icon1_32x32" DefaultValue="https://qaparrot365.wittyparrot.com/resources/assets/images/wp_logo_32px.png">
</bt:Image>
<bt:Image id="icon1_80x80" DefaultValue="https://qaparrot365.wittyparrot.com/resources/assets/images/wp_logo_80px.png">
</bt:Image>
<bt:Image id="icon2_32x32" DefaultValue="https://qaparrot365.wittyparrot.com/resources/assets/images/wp_logo_32px.png">
</bt:Image>
<bt:Image id="icon3_32x32" DefaultValue="https://qaparrot365.wittyparrot.com/resources/assets/images/wp_logo_32px.png">
</bt:Image>
</bt:Images>
<bt:Urls>
<bt:Url id="residDesktopFuncUrl" DefaultValue="https://qaparrot365.wittyparrot.com?source=msoffice">
</bt:Url>
<bt:Url id="residUnitConverterUrl" DefaultValue="https://qaparrot365.wittyparrot.com?source=msoffice">
</bt:Url>
<!--LearnMore URL currently not used -->
<bt:Url id="Witty.GetStarted.LearnMoreUrl" DefaultValue="https://qaparrot365.wittyparrot.com">
</bt:Url>
</bt:Urls>
<bt:ShortStrings>
<bt:String id="residLabel" DefaultValue="Launch Widget">
</bt:String>
<bt:String id="residLabel3" DefaultValue="Parrot365">
</bt:String>
<bt:String id="residLabel4" DefaultValue=" ">
</bt:String>
<bt:String id="Witty.GetStarted.Title" DefaultValue="Parrot365 Widget Loaded Successfully">
</bt:String>
</bt:ShortStrings>
<bt:LongStrings>
<bt:String id="residToolTip" DefaultValue="Parrot365 add-in provides improves productivity, accuracy and consistency in communication.">
</bt:String>
<bt:String id="Witty.GetStarted.Description" DefaultValue="Get going by opening the Home tab on the Ribbon then click Parrot365 button">
</bt:String>
</bt:LongStrings>
</Resources>
</VersionOverrides>
</OfficeApp>
'use strict';
var count = 0;
(function() {
\t angular.module('wpoffice')
\t \t .directive('wittyWordVariable', function() {
\t \t \t return {
\t \t \t \t restrict: 'E',
\t \t \t \t replace: true,
\t \t \t \t templateUrl: 'app/components/witty-word-variable/witty-word-variable_template.html',
\t \t \t \t scope: {},
\t \t \t \t bindToController: true,
\t \t \t \t controller: 'WordVariableController',
\t \t \t \t controllerAs: 'WordVariableCtrl'
\t \t \t };
\t \t })
\t \t .controller('WordVariableController', WordVariableController);
\t function WordVariableController($q, ngNotify) {
\t \t var vm = this;
\t \t vm.init = init;
\t \t vm.getSelectedWordFromDocument = getSelectedWordFromDocument;
\t \t vm.populateWordVar = populateWordVar;
\t \t function init() {
console.log('Initialized WordVariableController');
\t \t \t vm.inputBoxObjects = [];
\t \t \t vm.varValues = [];
\t \t \t vm.onloadVariablesFound = [];
\t \t \t if (Office.context.document) {
\t \t \t \t getAllSelectedContentControl();
\t \t \t } else {
\t \t \t \t ngNotify.set('Please reload Parrot365', 'error');
\t \t \t }
\t \t }
/*
*getAllSelectedContentControl----it will load the variable and corresponding text box
*@param --- no param
*/
\t \t function getAllSelectedContentControl() {
console.log('getAllSelectedContentControl');
console.log(Word);
Word.run(function(context) {
console.log('inside getSelectedContentControl 2');
var thisDocument = context.document;
context.load(thisDocument, 'contentControls/id, contentControls/text, contentControls/tag');
return context.sync().then(function() {
console.log('returned getSelectedContentControl');
if (thisDocument.contentControls.items.length !== 0) {
console.log(thisDocument.contentControls.items.length);
for (var i = 0; i < thisDocument.contentControls.items.length; i++) {
var variableLabel = thisDocument.contentControls.items[i].text;
var tagId = thisDocument.contentControls.items[i].tag;
if (tagId) {
getVarArray(variableLabel,tagId).then(function(arrayObj) {
createInputboxes(arrayObj);
});
}
}
} else {
console.log('Content is empty');
}
});
}).then(function() {
console.log('completed');
})
.catch(function(error) {
console.log('Error: ' + error);
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
console.log('Error code and message: ' + error.toString());
}
});
\t \t }
/*
*getVarArray----creates object on load
*@param variablevalue---value of variable
*@param TagId -----id of variable
*/
\t \t function getVarArray(variablevalue,tagId)
{
\t \t \t var deferred = $q.defer();
\t \t \t var allBindings = [];
var tagPrefix, variableLabel;
\t \t \t \t if (tagId && tagId.lastIndexOf("__") != -1) {
\t \t \t \t \t tagPrefix = tagId.substr(0,tagId.lastIndexOf('__'));
var index = tagId.indexOf("_");
if(index) {
variableLabel = tagId.substr(0,index);
}
\t \t \t \t }
\t \t \t \t var temp = {
\t \t \t \t \t 'id': tagId,
\t \t \t \t \t 'variableLabel': variableLabel,
\t \t \t \t \t 'tagPrefix': tagPrefix,
'value': variablevalue
\t \t \t \t };
\t \t \t \t var indexOfBinding = _.findIndex(allBindings, {
\t \t \t \t \t variableLabel: variableLabel,
\t \t \t \t \t tagPrefix: tagPrefix
\t \t \t \t });
\t \t \t \t if (indexOfBinding === -1) {
\t \t \t \t \t allBindings.push(temp);
\t \t \t \t }
\t \t \t \t deferred.resolve(allBindings);
\t \t \t return deferred.promise;
\t \t }
/*
*createInputboxes ----call createVariable function which will create scope obj
*/
\t \t function createInputboxes(arrayOfBindinds)
{
\t \t \t angular.forEach(arrayOfBindinds, function(binding) {
\t \t \t \t console.log(binding);
var textBoxValue = binding.value ? binding.value:'Enter Text';
console.log(binding.variableLabel+'===='+binding.tagPrefix+'===='+textBoxValue+'===='+binding.id);
\t \t \t \t createVariable (binding.variableLabel,binding.tagPrefix,textBoxValue,binding.id);
\t \t \t });
\t \t }
\t \t /*getSelectedWord - Get Selected Data from the document which user has selected manually.
\t \t *@no param
\t \t *called on user selection
\t \t *
\t \t */
\t \t function getSelectedWordFromDocument()
{
console.log('abc');
\t Word.run(function(context) {
console.log('inside word.run');
\t \t \t var range = context.document.getSelection();
\t \t \t var ContentControlForSelection = range.insertContentControl();
\t \t \t ContentControlForSelection.load('text');
\t \t \t return context.sync().then(function() {
\t \t \t \t var variableLabel = ContentControlForSelection.text;
\t \t \t \t var tagPrefix = variableLabel + '_tag';
\t \t \t \t ContentControlForSelection.tag = tagPrefix + '__' + count;
\t \t \t \t //var conditionalVariable = 'Onseletion';
\t \t \t \t //createVariable(variableLabel, tagPrefix);
console.log('variable created with'+variableLabel);
getVarArrayOnSelection(ContentControlForSelection.tag,variableLabel, tagPrefix).then(function(bindings) {
console.log(bindings);
createInputboxes(bindings);
});
\t \t \t });
\t \t })
\t \t .catch(function(error) {
\t \t \t console.log('Error: ' + error);
\t \t \t if (error instanceof OfficeExtension.Error) {
\t \t \t \t console.log('Debug info: ' + JSON.stringify(error.debugInfo));
\t \t \t }
\t \t });
}
/*
*getVarArrayOnSelection --- it creates obj for selected word in document
*@param--tagId
*@param--userSelectedText
*@param--tagPrefix
*/
\t \t function getVarArrayOnSelection(tagId,userSelectedText,tagPrefix)
{
\t \t \t var deferred = $q.defer();
\t \t \t var allBindings = [];
\t \t \t var temp = {
'id': tagId,
\t \t \t \t 'variableLabel': userSelectedText,
\t \t \t \t 'tagPrefix': tagPrefix
\t \t \t };
\t \t \t var indexOfBinding = _.findIndex(allBindings, {
\t \t \t \t variableLabel: userSelectedText,
\t \t \t \t tagPrefix: tagPrefix
\t \t \t });
\t \t \t if (indexOfBinding === -1) {
\t \t \t \t allBindings.push(temp);
\t \t \t }
\t \t \t deferred.resolve(allBindings);
\t \t \t return deferred.promise;
\t \t }
\t \t function createVariable(variableLabel, tagPrefix, newValue, id) {
console.log(variableLabel+'===='+ tagPrefix+'===='+ newValue+'===='+ id);
\t \t \t var flag = false;
\t \t \t var inputObj = {
\t \t \t \t id: id,
\t \t \t \t label: variableLabel,
\t \t \t \t tag: tagPrefix,
\t \t \t \t value: newValue
\t \t \t };
\t \t \t if (vm.inputBoxObjects.length > 0) {
\t \t \t \t var index = _.findIndex(vm.inputBoxObjects, {
\t \t \t \t \t label: variableLabel
\t \t \t \t });
\t \t \t \t if (index === -1) {
\t \t \t \t \t vm.inputBoxObjects.push(inputObj);
\t \t \t \t } else {
\t \t \t \t \t console.log('it already exists in the array');
\t \t \t \t }
\t \t \t } else {
\t \t \t \t vm.inputBoxObjects.push(inputObj);
\t \t \t }
\t \t }
\t \t /*populateWordVar
\t \t *@TextBoxId = Text Box Id
\t \t *@tagPrefix = unique identifier
\t \t **/
\t \t function populateWordVar(obj, $event, $index)
{
\t \t \t console.log(obj);
var TextboxValue = ($event.target.value === '' ? obj.label : $event.target.value);
console.log(TextboxValue);
Word.run(function (context) {
var contentControlsWithTag = context.document.contentControls.getByTag(obj.id);
context.load(contentControlsWithTag, 'text');
return context.sync().then(function() {
if (contentControlsWithTag.items.length === 0) {
console.log("There isn't a content control with a tag in this document.");
} else {
console.log('The first content control with the tag has this text: ' + contentControlsWithTag.items[0].text);
for (var i = 0;i<contentControlsWithTag.items.length;i++){
contentControlsWithTag.items[i].insertHtml(TextboxValue, 'Replace');
}
}
});
})
.catch(function (error) {
console.log('Error: ' + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
\t \t }
\t }
})();
<div class="flex layout-column pad-box-10 profile-container" ng-init="WordVariableCtrl.init()">
<div class="layout-row">
<button class="ms-Button ms-Button--primary" ng-click="WordVariableCtrl.getSelectedWordFromDocument()">
<span class="ms-Button-label">Create Variable</span>
</button>
</div>
<div class="layout-row">
<div class="layout-column">
<div ng-if="WordVariableCtrl.inputBoxObjects.length > 0" class="layout-row flex layout-align-start-center margin-d-10" id="innerDiv" data-ng-repeat="inputBox in WordVariableCtrl.inputBoxObjects">
<label class="ms-Label margin-r-10" for="{{inputBox.id}}" style="width:40%;overflow: hidden;display: inline-block;
text-overflow: ellipsis;white-space: nowrap;">{{inputBox.label}}</label>
<input type="text" name="" placeholder="Enter value" value="{{inputBox.value}}" id={{inputBox.id}} ng-blur="WordVariableCtrl.populateWordVar(inputBox,$event,$index)" class="ms-TextField-field flex flex-rem send-email-input">
</div>
</div>
</div>
</div>
請提供更多詳細信息。什麼是失敗的代碼?它失敗了什麼?什麼是「服務器」(是Office 365,還是本地?) –
當項目從本地Gulp服務時,它工作正常。但是,當相同的代碼部署在Apache服務器上時,Word.run()塊永遠不會執行,沒有控制檯錯誤或警告需要跟蹤。 – Leo
沒有錯誤信息或看到失敗的代碼,沒有太多可以繼續。請發佈您的清單,失敗代碼片段和服務器上記錄的任何錯誤。 –