1. App Web & Host Web

The special website to which the app is deployed is called an App Web.

The website to which the app is installed is called the Host Web.

例子:

Suppose, you are developing a SharePoint 2013 app for your organization. In that, you would require the App to access and to use the SharePoint components such as the lists, content types, workflows, and pages. In this Case, all your SharePoint components should be deployed in a separate SharePoint site, called as the App Web.
 
The Host Web is nothing but the SharePoint site where the App is actually installed. So, to conclude, all the resources accessed by a SharePoint web has to be deployed in a different site, named as the App web. And, the actual site where the app is deployed (from VS) is called the Host Web.
 
2. Client Authentication with Office 365
使用SharePointOnlineCredentials对象
ClientContext context = new ClientContext(url);
System.Security.SecureString passWord = new System.Security.SecureString();
foreach (char c in password.ToCharArray())
{
passWord.AppendChar(c);
}
context.Credentials = new SharePointOnlineCredentials(userName, passWord);

3. App中的Client Web Part是否加入到Feature或者package中不影响App中的内容,App文件会将项目中的所有信息加入进去;

4. App的链接中已默认包含了这个参数:SPHostUrl, SPLanguage, SPClientTag, SPProductNumber, 和SPAppWebUrl。

5. 动态创建Tile的方法:

在页面上定义一个container:

<!-- Tiles will be rendered here -->
<div id="tileArea" style="width:600px;"></div>

定义CSS:

/* Custom styles for the tiles */
.tile{
width:150px;
height:150px;
color:#FFFFFF;
margin-top:5px;
margin-left:0px;
margin-right:10px;
margin-bottom:10px;
cursor:pointer;
padding:5px;
float:left;
text-align:right;
font-family:Segoe UI, sans-serif;
font-size:14px;
background-image:url(../images/MetroPlay.png);
background-repeat: no-repeat;
background-position:bottom right;
background-color:#FFAAAA;
}
.tileNumber{
text-align:center;
font-family:Segoe UI Light, sans-serif;
font-size:72px;
margin-top:10px;
margin-bottom:10px;
}
a, a:hover, a:visited {text-decoration:none; outline:none;color:#FFFFFF}
a:active, a:focus {outline:}

使用JavaScript,根据列表数目动态生成tile:

// Variables used to hold objects for use in callback functions
var context;
var lists;
//var list;
var listItems;
var tileArea;
// This code runs when the DOM is ready and creates a context object which is needed
// to use the SharePoint object model
$(document).ready(function () { context = SP.ClientContext.get_current();
var web = context.get_web();
lists = web.get_lists();
context.load(lists);
context.executeQueryAsync(Function.createDelegate(this, renderListTiles), Function.createDelegate(this, errorLoadingLists));
}); function errorLoadingLists(sender, args) {
tileArea = document.getElementById("tileArea"); // Remove all nodes from the chart <DIV> so we have a clean space to write to
while (tileArea.hasChildNodes()) {
tileArea.removeChild(tileArea.lastChild);
} // Write a message to let the user know the operation has failed
var errMessage = document.createElement("div");
errMessage.appendChild(document.createTextNode("Lists could not be retrieved."+args.get_message()));
} function renderListTiles(sender, args) {
var listEnumerator = lists.getEnumerator(); while (listEnumerator.moveNext()) {
var list = listEnumerator.get_current();
var listTitle = list.get_title();
if ((listTitle == "Employees") || (listTitle == "MarketSize") || (listTitle == "Sales")) {
var itemCount = list.get_itemCount();
var tile = document.createElement("a");
tile.setAttribute("class", "tile");
tile.setAttribute("href", "../Lists/" + listTitle);
tile.appendChild(document.createTextNode(listTitle)); $("#tileArea").appendChild(tile);
var tileBody = document.createElement("div");
tileBody.setAttribute("class", "tileNumber");
tileBody.appendChild(document.createTextNode(itemCount.toString()));
tile.appendChild(tileBody);
}
}
}

效果:

6. 向SharePoint Log中添加记录时,需要用到SP.Analytics命名空间(SP.js);

 var eventGuid = new SP.Guid("101c16a5-3abd-4020-921f-cc40090c6ff7");

    // When you have entered a valid GUID, you can then call the logAnalyticsAppEvent
// as follows:
SP.Analytics.AnalyticsUsageEntry.logAnalyticsAppEvent(context, eventGuid, "Test App Page");
context.executeQueryAsync( // This is the success callback:
function () {
status.innerText = "Success! The event for 'Test App Page' has been logged.";
}, // This is the failure callback:
function (sender, e) {
status.innerText = "Failed to log event for 'Test App Page': " + e.get_message();
});

7. sp.userprofiles.js中包含了获取user profle信息的方法和对象(但除了accountName属性,其它属性可能为null)

// This code runs when the DOM is ready and creates a context object
// which is needed to use the SharePoint object model. We also wire
// up the click event handler of the listProfiles button in default.aspx.
$(document).ready(function () {
context = SP.ClientContext.get_current();
$('#listProfiles').click(function () { listProfilesClick();});
}); // This function handles the click event of the listProfiles button in default.aspx
function listProfilesClick() { // Our way into the current user's profile is through the PeopleManager class
// so we'll instantiate a new object and pass in the current context,
peopleMgr = new SP.UserProfiles.PeopleManager(context); // We'll then load the object...
context.load(peopleMgr); // ... and we'll get the user profile properties and load them as well.
profileProperties = peopleMgr.getMyProperties();
context.load(profileProperties); // Next we ask SharePoint to run all of our previously batched commands...
context.executeQueryAsync( // ... and if we're successful, the following success callback will run
function () { if (peopleMgr.get_isMyPeopleListPublic()) {
publicDiv.appendChild(document.createTextNode("Your followers and those you follow are publicly visible"));
}
else {
publicDiv.appendChild(document.createTextNode("Your followers and those you follow are not publicly visible"));
}
$('#profileList').append(publicDiv); // Then we'll add a few simple properties from the profile.
// The first one is the account name
var accountName = profileProperties.get_accountName(); // The second one is the display name.
// Note that we'll check for null in case this property hasn't been set.
var displayName = profileProperties.get_displayName(); // The third thing to show the user is their profile picture.
// Note that we'll check for null in case this property hasn't been set.
// If it's not null, we'll render the actual picture.
var myPicture = profileProperties.get_pictureUrl(); // Finally, we'll add three links:
// One for editing the profile...
var myProfileLink = peopleMgr.get_editProfileLink(); // One for going to the user's personal site...
var myPersonalSite = profileProperties.get_personalUrl(); // And one that shows the user what their page looks like when
// viewed by other users.
var myPublicPersona = profileProperties.get_userUrl(); }, // If we haven't been successful, the following failure callback
// will run, so we'll clear the profile list div, and then use it
// to tell the user what went wrong
function (sender, e) {
$('#profileList').children().remove();
$('#profileList').append(docume.createTextNode(e.get_message()));
});
}

8. SP.RequestExecutor.js文件就是cross-domain library,SP.RequestExecutor对象用于执行与其它数据源交互的操作,比如host-web,app-web;但需要注意的是,如果在APP中使用SP.RequestExecutor对象与Host Web的数据进行交互,由于在App中,默认的context site是app web, 所以我们还需要使用SP.AppContextSite()来设置当前的context site为 host web,然后还要再AppManifest.xml中设置app在host web中的权限(在使用SP.AppContextSite时必须使用SP.AppContextSite(@target) 和?@target='<host web url>'的格式,不能直接将host web地址写在参数括号中);

var hostweburl;
var appWebUrl; // Load the required SharePoint libraries
$(document).ready(function () {
//Get the URI decoded URLs.
hostweburl =
decodeURIComponent(
getQueryStringParameter("SPHostUrl")
); appWebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl")); // Load the js file and continue to the
// success event handler
$.getScript(hostweburl+"/_layouts/15/SP.RequestExecutor.js", execCrossDomainRequest);
}); // Function to prepare and issue the request to get
// SharePoint data
function execCrossDomainRequest() {
var executor; // Initialize the RequestExecutor with the app web URL.
executor = new SP.RequestExecutor("/"); // Issue the call against the host web.
// To get the title using REST we can hit the endpoint:
// app_web_url/_api/SP.AppContextSite(@target)/web/title?@target='siteUrl'
// The response formats the data in the JSON format.
// The functions successHandler and errorHandler attend the
// success and error events respectively.
executor.executeAsync(
{
url:
appWebUrl+"/_api/SP.AppContextSite(@target)/web/title?@target='" +
hostweburl + "'",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: successHandler,
error: errorHandler
}
);
} // Function to handle the success event.
// Prints the host web's title to the page.
function successHandler(data) {
var jsonObject = JSON.parse(data.body); document.getElementById("HostwebTitle").innerHTML =
"<b>" + jsonObject.d.Title + "</b>";
} // Function to handle the error event.
// Prints the error message to the page.
function errorHandler(data, errorCode, errorMessage) {
document.getElementById("HostwebTitle").innerText =
"Could not complete cross-domain call: " + errorMessage;
}

9.  在app中搜索host web内容时,需要在AppManifest.xml文件的Permissions中为app添加Search权限,搜索时使用的url路径就是app web的路径,但依然可以搜索到host web的内容;

function executeQuery() {
alert(_spPageContextInfo.webAbsoluteUrl);
$.ajax(
{
url: _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='" + $("#queryTerms").val() + "'",
method: "GET",
headers: {
"Accept": "application/json;odata=verbose"
},
success: onSuccess,
error: onError
}
);
} function onSuccess(data) {
var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
alert(JSON.stringify(data.d.query)); //display json as string
var html = "<table>"; for (var i = 0; i < results.length; i++) {
html += "<tr><td>";
html += results[i].Cells.results[3].Value;
html += "</td><td>"
html += results[i].Cells.results[6].Value;
html += "</td><tr>";
} html += "</table>"; $("#resultsDiv").append($(html));
} function onError(err) {
alert(JSON.stringify(err));
}

10. _spPageContextInfo.webAbsoluteUrl可以直接在app中获取到当前站点的web绝对路径;

11.

SharePoint 2013 - Add-ins的更多相关文章

  1. SharePoint 2013 create workflow by SharePoint Designer 2013

    这篇文章主要基于上一篇http://www.cnblogs.com/qindy/p/6242714.html的基础上,create a sample workflow by SharePoint De ...

  2. SharePoint 2013 configure and publish infopth

    This article will simply descript how to configure and publish a InfoPath step by step. Note: To con ...

  3. Integrating SharePoint 2013 with ADFS and Shibboleth

    Time again to attempt to implement that exciting technology, Federation Services (Web Single Sign On ...

  4. office 365 Sharepoint 2013

    平台环境: office 365 Sharepoint  2013 操作文件和文件夹 访问文档库的最佳方式是借助在 /_api/web 处可用的 GetFolderByServerRelativeUr ...

  5. SharePoint 2013 版本功能对比

    前言:在SharePoint使用中,经常纠结于版本问题,SharePoint 2013主要有免费的Foundation和收费的标准版.企业版三个版本,他们之间的功能上是不一样的,找了一些资料才发现下面 ...

  6. SharePoint 2013 Search REST API 使用示例

    前言:在SharePoint2013中,提供Search REST service搜索服务,你可以在自己的客户端搜索方法或者移动应用程序中使用,该服务支持REST web request.你可以使用K ...

  7. SharePoint 2013 文档库中PPT转换PDF

    通过使用 PowerPoint Automation Services,可以从 PowerPoint 二进制文件格式 (.ppt) 和 PowerPoint Open XML 文件格式 (.pptx) ...

  8. SharePoint 2013 Word 转换PDF服务介绍及示例

    前言:在SharePoint使用过程中,经常会发现将文档进行格式转换的需求,之前,看到SharePoint 2013有将PPT转换PDF文档的服务,后来,才发现SharePoint 2010开始,就有 ...

  9. SharePoint 2013 状态机工作流之UpdateItemActivity

    没什么可说的,一个Activity的使用介绍,其他类似的Activity也可以参考这个使用. 1.添加ApplyActivation和UpdateItemActivity,在onWorkflowAct ...

  10. SharePoint 2013 状态机工作流之日常报销示例

    简单介绍下状态机工作流,状态机工作流提供了一系列的状态.工作流从初始状态开始,到终止状态结束.两个状态之间定义行为进行过渡.通常情况下,状态机工作流对事件作出反应,事件的发生将会使状态发生改变. 1. ...

随机推荐

  1. JUnit4.13环境配置

    Junit 4.13环境配置 JUnit是一个强大的单元测试工具.它可以针对某一个特定类的所有方法进行精确打击.这个东西具体怎么使用,留在以后说.这次给大家说说idea下配置JUnit环境的方法. 1 ...

  2. json、xml

    json:(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然 ...

  3. pip 使用代理

    pip install -i https://mirrors.aliyun.com/pypi/simple/ opencv-python 红色部分 代表使用 阿里云 代理 安装 pip

  4. LCT小小结

    模板题P3690 基础题P3203[HNOI2010]弹飞绵羊 \(access\)是搞出一条端点为\(x,y\)的路径 , 且维护的是实子树的信息 . 由于题目比较简单 , \(access\)时还 ...

  5. [BZOJ 3262]陌上开花

    今天写了到偏序问题,发现博主真的是个傻X 传送门 以前的写法 /************************************************************** Probl ...

  6. Kibana6.x.x---编译源码,在执行优化任务时,报警告

    wangxuan@tryman:/home/kibana_git/kibana6.2.2$ yarn release yarn run v1.5.1 $ grunt release Running & ...

  7. bzoj4548: 小奇的糖果 题解

    题目链接 题解 不包含所有颜色 就强制不选一个颜色 图中圆点颜色相同 矩形越大,包括的点一定不比其一小部分少 如图所示,最大矩形只有3种 离散化\(x\)坐标 然后按\(y\)排序 每次取出颜色的前驱 ...

  8. 挑战程序设计竞赛 P131 区间DP

    书上好多题没补 PS.整个DP是根据Q来划分的,dalao的代码就是不一样啊 #include<bits/stdc++.h> #define rep(i,j,k) for(int i=j; ...

  9. 自动判断文本文件编码来读取文本文件内容(.net版本和java版本)

    .net版本 using System; using System.IO; using System.Text; namespace G2.Common { /// <summary> / ...

  10. php安装composer

    php.ini打开三个扩展: extension=php_mbstring.dll extension=php_openssl.dll extension=php_pdo_mysql.dll