绑定对象(Word)
网址:https://dev.office.com/reference/add-ins/shared/bindings.bindings
创建对变量的绑定:
填充内容
的问题:
没有控制台错误或警告,但是当尝试通过服务器执行代码时,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() {
angular.module('wpoffice')
.directive('wittyWordVariable', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'app/components/witty-word-variable/witty-word-variable_template.html',
scope: {},
bindToController: true,
controller: 'WordVariableController',
controllerAs: 'WordVariableCtrl'
};
})
.controller('WordVariableController', WordVariableController);
function WordVariableController($q, ngNotify) {
var vm = this;
vm.init = init;
vm.getSelectedWordFromDocument = getSelectedWordFromDocument;
vm.populateWordVar = populateWordVar;
function init() {
console.log('Initialized WordVariableController');
vm.inputBoxObjects = [];
vm.varValues = [];
vm.onloadVariablesFound = [];
if (Office.context.document) {
getAllSelectedContentControl();
} else {
ngNotify.set('Please reload Parrot365', 'error');
}
}
/*
*getAllSelectedContentControl----it will load the variable and corresponding text box
*@param --- no param
*/
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());
}
});
}
/*
*getVarArray----creates object on load
*@param variablevalue---value of variable
*@param TagId -----id of variable
*/
function getVarArray(variablevalue,tagId)
{
var deferred = $q.defer();
var allBindings = [];
var tagPrefix, variableLabel;
if (tagId && tagId.lastIndexOf("__") != -1) {
tagPrefix = tagId.substr(0,tagId.lastIndexOf('__'));
var index = tagId.indexOf("_");
if(index) {
variableLabel = tagId.substr(0,index);
}
}
var temp = {
'id': tagId,
'variableLabel': variableLabel,
'tagPrefix': tagPrefix,
'value': variablevalue
};
var indexOfBinding = _.findIndex(allBindings, {
variableLabel: variableLabel,
tagPrefix: tagPrefix
});
if (indexOfBinding === -1) {
allBindings.push(temp);
}
deferred.resolve(allBindings);
return deferred.promise;
}
/*
*createInputboxes ----call createVariable function which will create scope obj
*/
function createInputboxes(arrayOfBindinds)
{
angular.forEach(arrayOfBindinds, function(binding) {
console.log(binding);
var textBoxValue = binding.value ? binding.value:'Enter Text';
console.log(binding.variableLabel+'===='+binding.tagPrefix+'===='+textBoxValue+'===='+binding.id);
createVariable (binding.variableLabel,binding.tagPrefix,textBoxValue,binding.id);
});
}
/*getSelectedWord - Get Selected Data from the document which user has selected manually.
*@no param
*called on user selection
*
*/
function getSelectedWordFromDocument()
{
console.log('abc');
Word.run(function(context) {
console.log('inside word.run');
var range = context.document.getSelection();
var ContentControlForSelection = range.insertContentControl();
ContentControlForSelection.load('text');
return context.sync().then(function() {
var variableLabel = ContentControlForSelection.text;
var tagPrefix = variableLabel + '_tag';
ContentControlForSelection.tag = tagPrefix + '__' + count;
//var conditionalVariable = 'Onseletion';
//createVariable(variableLabel, tagPrefix);
console.log('variable created with'+variableLabel);
getVarArrayOnSelection(ContentControlForSelection.tag,variableLabel, tagPrefix).then(function(bindings) {
console.log(bindings);
createInputboxes(bindings);
});
});
})
.catch(function(error) {
console.log('Error: ' + error);
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
}
/*
*getVarArrayOnSelection --- it creates obj for selected word in document
*@param--tagId
*@param--userSelectedText
*@param--tagPrefix
*/
function getVarArrayOnSelection(tagId,userSelectedText,tagPrefix)
{
var deferred = $q.defer();
var allBindings = [];
var temp = {
'id': tagId,
'variableLabel': userSelectedText,
'tagPrefix': tagPrefix
};
var indexOfBinding = _.findIndex(allBindings, {
variableLabel: userSelectedText,
tagPrefix: tagPrefix
});
if (indexOfBinding === -1) {
allBindings.push(temp);
}
deferred.resolve(allBindings);
return deferred.promise;
}
function createVariable(variableLabel, tagPrefix, newValue, id) {
console.log(variableLabel+'===='+ tagPrefix+'===='+ newValue+'===='+ id);
var flag = false;
var inputObj = {
id: id,
label: variableLabel,
tag: tagPrefix,
value: newValue
};
if (vm.inputBoxObjects.length > 0) {
var index = _.findIndex(vm.inputBoxObjects, {
label: variableLabel
});
if (index === -1) {
vm.inputBoxObjects.push(inputObj);
} else {
console.log('it already exists in the array');
}
} else {
vm.inputBoxObjects.push(inputObj);
}
}
/*populateWordVar
*@TextBoxId = Text Box Id
*@tagPrefix = unique identifier
**/
function populateWordVar(obj, $event, $index)
{
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));
}
});
}
}
})();
<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>
答案 0 :(得分:1)
您的清单宣布您的加载项适用于Word,PowerPoint和Excel,但它指向的代码是利用Word Api。您应该确保您的清单声明对Word API的依赖并删除Excel和PowerPoint。这将确保加载项仅显示支持的位置。
代码严重缩小,难以准确理清它正在做什么。我怀疑您的问题是您使用Word API尚未支持的Word API 1.3或1.4进行呼叫。这可以解释为什么您在桌面上使用Word时看到了正确的行为,但在与Word Online一起使用时却没有。我建议查看代码,以确保您不会依赖任何new methods introduced with 1.3。
您还要从您的清单中将params传递到应用程序中。您的加载项的源页面不应该依赖于参数。此处的指导是为您的加载项使用唯一的登录页面。您可以在加载项初始化后将用户重定向到新的URI,并且已建立Word和加载项之间的通信通道。
答案 1 :(得分:0)
关于设定数据,我已在您的其他问题中回答了这个问题:Office js API setDataAsync not working as suggested in Document