SharePoint 客户端对象模型 (一) ECMA Script


Posted in Javascript onMay 22, 2011

所谓的客户端对象模型就是调用了背后的WCF服务来提供数据,为了减轻数据的访问量数据包使用JSON,我们还可以看到对象模型的设计也加入了诸多对于减轻数据访问量的考量。技术上没有什么新意,你要愿意,在SharePoint2007里面也可以实现类似的功能,当然在使用上方便了我们不少

SharePoint 客户端对象模型 (一) ECMA Script 
三种使用客户端模型的.NET托管、ECMA脚本,SilverLightClient.

SharePoint 客户端对象模型 (一) ECMA Script

本文讲阐述如何使用.NET托管代码来访问SharePoint对象模型。

ECMAScript Client OM需要注意的几个点

  • ECMAScript仅能够在SharePoint站点里面使用,不能够在其他的Asp.NET站点里使用ECMAScript来访问SharePoint站点资源,也不能够跨SharePoint站点访问资源;
  • JQuery和ECMAScript使用起来不会有冲突;
  • 为了安全的更新内容,在使用ECMAScript的画面里添加<SharePoint:FormDigest runat="server" />
  • 在随后你将会看到的代码里为了减轻加载的数据量,可以指定需要加载的内容,例如client.Context.load(this.web,'Title','Id','Created'), 这里的属性值名称使用和CAML一样的体系,对大小写敏感;
  • 为确保你的代码执行在SP.JS加载完之后再被调用,可以使用ExecuteOrDelayUntilScriptLoaded(myjsFunction, “sp.js”)。

我们看看SharePoint OM和客户端OM的一个简单的匹配关系:

服务器端OM 客户端OM
SPContext ClientContext
SPSite Site
SPWeb Web
SPList List
SPListItem ListItem
SPField Field

看看最后会呈现的效果,下图是初步计划的功能,主要设计列表的创建、查询以及管理,另外也涉及上传文件的Case,后续里如果有重要的也会逐步加进来。

SharePoint 客户端对象模型 (一) ECMA Script

里面的链接会调用UI方面的Javascript接口创建SharePoint2010风格的弹出窗口,弹出窗口的后台页面位于SitePage文档库内,请注意这个仅仅适用于打开的页面是WebPart page,如果不是打开的时候会报错误:“The Ribbon Tab with id: "Ribbon.Read" has not been made available for this page or does not exist”。

(注意,此Page在之后都不会被用到,留在这里仅为了解释Ribbon用)

创建列表:

首先,通过Designer,加入以下两个Script链接:

<SharePoint:ScriptLink Name="SP.js" runat="server" OnDemand="true" Localizable="false" />
<SharePoint:ScriptLink Name="SP.debug.js" runat="server" OnDemand="true" Localizable="false" />

ECMAScriptOM和.NET Managed ClientOM(随后会讲到)异曲同工,但也有几点需要注意的:

  1. 在ClientContext里面不能使用服务器端URLs;
  2. 不支持LINQ;
  3. 本质上ECMAScript OM是异步的

代码非常的简单易懂,里面有个好玩的东西SP.UI.Notify.addNotification,通过这个类可以在调用的画面里显示提示消息,非常的SharePoint。

SharePoint 客户端对象模型 (一) ECMA Script

演示结果如下:

在文本框里输入列表名字后,点击"Create List”按钮,生成列表后会在右上角提示“List test1 created”,本例中使用annoucement做为列表类型。

SharePoint 客户端对象模型 (一) ECMA Script

源代码如下:

<script type="text/javascript"> 
var messageId; 
function createList(listName){ 
var clientContext = new SP.ClientContext(); 
var oWebSite = clientContext.get_web(); 
var listCreationInfo = new SP.ListCreationInformation(); 
listCreationInfo.set_title(listName); 
listCreationInfo.set_templateType(SP.ListTemplateType.announcements); 
listCreationInfo.set_quickLaunchOption(SP.QuickLaunchOptions.on); 
var oList = oWebSite.get_lists().add(listCreationInfo); 
clientContext.load(oList); 
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed)); 
} 
function onQuerySucceeded() { 
//Remove the 'creating' event notification 
if(messageId != null) 
{ 
SP.UI.Notify.removeNotification(messageId); 
} 
//Add 'created' notification as non sticky 
messageId = SP.UI.Notify.addNotification("List <b>" + oList.get_title() + "</b> created...", false, "", null); 
} function onQueryFailed(sender, args) { 
//Remove the 'creating' event notification 
if(messageId != null) 
{ 
SP.UI.Notify.removeNotification(messageId); 
} 
//Shown in case of error on the JS OM call 
messageId = SP.UI.Notify.addNotification("Operation was cancelled...", false, "", null); 
} 
</script>

获取所有列表:

同样,先看一下效果,点击“Get All List”按钮,会将当前站点下的所有列表都读取出来并设置了响应的超链接属性,点击“Hide List”按钮则将之隐藏(实际上就是个Div)

SharePoint 客户端对象模型 (一) ECMA Script

代码非常的直接,只说明一个点,getEnumerator()以及moveNexst(), get_current()等JavaScript函数的使用为遍历集合提供了很好的方法。

源代码:

function getLists(){ 
var clientContext = new SP.ClientContext(); 
var oWebSite = clientContext.get_web(); 
listCollection = oWebSite.get_lists(); 
clientContext.load(listCollection); 
clientContext.executeQueryAsync(Function.createDelegate(this, this.onGetListsSucceeded), Function.createDelegate(this, this.onGetListsFailed)); 
} 
function onGetListsSucceeded(){ 
var str = ""; 
var listsEnumerator = listCollection.getEnumerator(); 
while(listsEnumerator.moveNext()){ 
var objList = listsEnumerator.get_current(); 
str += "<a href='" + "http://localhost" + objList.get_parentWebUrl() + objList.get_defaultViewUrl() + "'>" + objList.get_title() + "</a>" + "<br/>"; 
} 
document.getElementById("lists").innerHTML = str; 
} 
function onGetListsFailed(sender, args){ 
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); 
}

CAML查询:

这里面提供了两种方式查询,一个按DueDate,一种按Title,当然功能可以设计的更加有利于用户使用些,Demo里就不做过多渲染。点击Search就可以进行数据的查询,有一点小发现,如果使用<asp:calendar/>控件的时候选择好日期会导致页面postback,SharePoint里面至少有两种解决方案:

  1. 单独在某个页面里面放入calendar控件,然后添加以下代码:

    <input type="text" id="txtDate" name="txtDate" />
    <button value="lookup" onclick="document.all['txtDate'].value =
    window.showModalDialog( 'Calendar.aspx' );" >

  2. 使用SharePoint Calendar控件<SharePoint:DateTimeControl runat=server id="DateTimeControl1" DateOnly="True"></SharePoint:DateTimeControl>

SharePoint 客户端对象模型 (一) ECMA Script

SharePoint 客户端对象模型 (一) ECMA Script

做了一段对控件显示的控制,选择Date则出现输入Date的控件,选择Title则出现输入Title的控件,本来想用JQuery的方法,后来一下没想起来JQuery的Selector写法,半土不洋的用了下面的方法结合控制:

<script type="text/javascript"> 
function changeQueryMethod(){ 
var method = $("select[id='selectQueryMethod']").val(); 
if(method == 'Title'){ 
document.getElementById('querybytitle').style.display = "inline"; 
document.getElementById('querybyDate').style.display = "none"; 
} 
else{ 
document.getElementById('querybytitle').style.display = "none"; 
document.getElementById('querybyDate').style.display = "inline"; 
} 
} 
</script>

关于CAML查询的细节本身也不做过多说明,如果有兴趣可以参见拙文(http://www.cnblogs.com/johnsonwong/archive/2011/02/27/1966008.html),这是一篇针对2007版本的CAML,在2010里有了很多增强,譬如跨列表Joint查询等,随后会发布相应2010的版本。

需要注意的知识是:

里面使用了对field的查询,注意相关API的调用;
ClientContext里面对若干个结果集进行操作,但需要调用Load对不同结果集进行加载:clientContext.load(fieldCollection);clientContext.load(listItemCollection);
如果有需要读取的字段值需要在CAML查询XML里面显示说明,否则不会返回到结果集里,这也是出于对性能的考虑

function search(){ 
var clientContext = new SP.ClientContext(); 
var oWebSite = clientContext.get_web(); 
var list = oWebSite.get_lists().getByTitle("Tasks"); 
fieldCollection = list.get_fields(); 
var camlQuery = new SP.CamlQuery(); 
camlQuery.set_viewXml( "<View><Query><Where><Gt>" + 
"<FieldRef Name='DueDate' />" + 
"<Value Type='DateTime'>2008-01-1T00:00:00Z</Value>" + 
"</Gt></Where></Query><ViewFields>" + 
"<FieldRef Name=\"Title\" /><FieldRef Name=\"Body\" />" + 
"<FieldRef Name=\"DueDate\" />" + 
"</ViewFields></View>"); 
listItemCollection = list.getItems(camlQuery); 
clientContext.load(fieldCollection); 
clientContext.load(listItemCollection); 
clientContext.executeQueryAsync(Function.createDelegate(this, this.onSearchListSucceeded), Function.createDelegate(this, this.onSearchListFailed)); 
} 
function onSearchListSucceeded(){ 
var str = ""; 
var listItemEnumerator = listItemCollection.getEnumerator(); 
var fieldsEnumerator = fieldCollection.getEnumerator(); 
while(listItemEnumerator.moveNext()){ 
var oListItem = listItemEnumerator.get_current(); 
str += "Item " + oListItem.get_id() + ":" 
while(fieldsEnumerator.moveNext()){ 
var oField = fieldsEnumerator.get_current(); 
str += oField.get_staticName() + "<br/>"; 
} 
str += "<br/>"; 
} 
document.getElementById("lists").innerHTML = str; 
} function onSearchListFailed(sender, args){ 
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); 
}

操作文件:

遗憾的是在ECMAScript里面无法上传文件,虽然有SP.File对象,但更多的是对获取回来的SP.File对象进行操作。

Javascript 相关文章推荐
使用Modello编写JavaScript类
Dec 22 Javascript
js 面向对象的技术创建高级 Web 应用程序
Feb 25 Javascript
IE6/7 and IE8/9/10(IE7模式)依次隐藏具有absolute或relative的父元素和子元素后再显示父元素
Jul 31 Javascript
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
Sep 22 Javascript
使用js实现一个可编辑的select下拉列表
Feb 20 Javascript
js身份证判断方法支持15位和18位
Mar 18 Javascript
jquery缓动swing liner控制动画过程不同时刻的速度
May 29 Javascript
轻量级javascript 框架Backbone使用指南
Jul 24 Javascript
JS实现区分中英文并统计字符个数的方法示例
Jun 09 Javascript
jQuery表单校验插件validator使用方法详解
Feb 18 jQuery
Vue实现鼠标经过文字显示悬浮框效果的示例代码
Oct 14 Javascript
JavaScript canvas实现跟随鼠标移动小球
Feb 09 Javascript
JQuery里选择超链接的实现代码
May 22 #Javascript
改善用户体验的五款jQuery插件分享
May 22 #Javascript
JS 进度条效果实现代码整理
May 21 #Javascript
jquery 使用点滴函数代码
May 20 #Javascript
JQuery对checkbox操作 (循环获取)
May 20 #Javascript
检测jQuery.js是否已加载的判断代码
May 20 #Javascript
JQuery datepicker 使用方法
May 20 #Javascript
You might like
比较全的PHP 会话(session 时间设定)使用入门代码
2008/06/05 PHP
php获取当月最后一天函数分享
2015/02/02 PHP
php安装swoole扩展的方法
2015/03/19 PHP
Laravel框架实现利用中间件进行操作日志记录功能
2018/06/06 PHP
不间断滚动JS打包类,基本可以实现所有的滚动效果,太强了
2007/12/08 Javascript
javascript 当前日期转化为中文的实现代码
2010/05/13 Javascript
offsetHeight在OnLoad中获取为0的现象
2013/07/22 Javascript
js实现键盘控制DIV移动的方法
2015/01/10 Javascript
适用于javascript开发者的Processing.js入门教程
2016/02/24 Javascript
HTML5 实现的一个俄罗斯方块实例代码
2016/09/19 Javascript
使用jQuery操作DOM的方法小结
2017/02/27 Javascript
bootstrap响应式导航条模板使用详解(含下拉菜单,弹出框)
2017/11/17 Javascript
React如何避免重渲染
2018/04/10 Javascript
JS使用栈判断给定字符串是否是回文算法示例
2019/03/04 Javascript
深入了解JavaScript 的 WebAssembly
2019/06/15 Javascript
JavaScript实现随机点名程序
2020/03/25 Javascript
原生js实现分页效果
2020/09/23 Javascript
[38:23]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第一场
2014/05/24 DOTA
[47:39]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs OPTIC
2018/03/31 DOTA
Python2.5/2.6实用教程 入门基础篇
2009/11/29 Python
关于Python中Inf与Nan的判断问题详解
2017/02/08 Python
python创建列表和向列表添加元素的实现方法
2017/12/25 Python
Python Datetime模块和Calendar模块用法实例分析
2019/04/15 Python
使用django实现一个代码发布系统
2019/07/18 Python
django Layui界面点击弹出对话框并请求逻辑生成分页的动态表格实例
2020/05/12 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
HTML5-WebSocket实现聊天室示例
2016/12/15 HTML / CSS
北美大型运动类产品商城:Champs Sports
2017/01/12 全球购物
赫里福德的一家乡村零售商店:Philip Morris & Son
2017/06/25 全球购物
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
Brother加拿大官网:打印机、贴标机、缝纫机
2019/10/09 全球购物
师范生个人推荐信
2013/11/29 职场文书
2014年征兵标语
2014/06/20 职场文书
安全生产年活动总结
2014/08/29 职场文书
团代会开幕词
2015/01/28 职场文书
学习党章心得体会2016
2016/01/15 职场文书