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.

最新文章

  1. npm link 安装本地模块,将本地模块cli化
  2. SpringJMS解析3-监听器
  3. 复习做UWP时涉及到的几种加密签名相关
  4. Android IOS WebRTC 音视频开发总结(六六)-- 三个角度分析美女视频直播这个行业
  5. .net 高效管理稀缺资源(数据库资源,文件资源等)
  6. OC内存管理基础
  7. C语言中随机数的生成
  8. css单位rem---移动端至宝
  9. 手把手封装数据层之DataUtil数据库操作的封装
  10. django中怎么使用自定义管理后台xadmin
  11. 安装cmake
  12. Python创建空DataFrame及添加行数据
  13. 复审Partner
  14. js动态检测加载 JQ
  15. Activiti工作流的应用示例
  16. python实现注册登录小程序
  17. PostgreSQL 传统 hash 分区方法和性能
  18. config的配置文件
  19. 各版本JDK官方下载地址
  20. 全球订单最多的成都优步推出&quot;南北通勤线&quot;业务

热门文章

  1. django&#39; 前端 self.status.split(&#39; &#39;,1)[0], self.bytes_sent AttributeError: &#39;NoneType&#39; object has no attribute &#39;split&#39;
  2. [Python]打印a..z的字符
  3. JavaWeb学习笔记(七)—— JSP
  4. 清华集训2017D2T1 小 Y 和地铁(metro)
  5. 简单探究一下window下的wifi各种东西
  6. 制作支持UEFI启动的原装系统安装盘
  7. [转] 使用Docker容器,这些错误千万别犯
  8. rm删除文件,空间没有释放
  9. 【Tensorflow】 Object_detection之liunx服务器安装部署步骤记录
  10. 最好用的数据存储Easy Save2讲解