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 相关文章推荐
利用js正则表达式验证手机号,email地址,邮政编码
Jan 23 Javascript
js 去除字符串第一位逗号的方法
Jun 07 Javascript
完美兼容各大浏览器的jQuery仿新浪图文淡入淡出间歇滚动特效
Nov 12 Javascript
javascript如何实现暂停功能
Nov 06 Javascript
微信小程序授权获取用户详细信息openid的实例详解
Sep 20 Javascript
浅析为什么a=&quot;abc&quot; 不等于 a=new String(&quot;abc&quot;)
Oct 25 Javascript
在 webpack 中使用 ECharts的实例详解
Feb 05 Javascript
vue axios基于常见业务场景的二次封装的实现
Sep 21 Javascript
浅谈VUE-CLI脚手架热更新太慢的原因和解决方法
Sep 28 Javascript
jQuery实现聊天对话框
Feb 08 jQuery
JavaScript数组类型Array相关的属性与方法详解
Sep 08 Javascript
Vue实现简单的留言板
Oct 23 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记录日志的实现代码
2011/08/08 PHP
5种PHP创建数组的实例代码分享
2014/01/17 PHP
php函数与传递参数实例分析
2014/11/15 PHP
PHP连接MySQL数据的操作要点
2015/03/20 PHP
PHP伪造来源HTTP_REFERER的方法实例详解
2015/07/06 PHP
php数字每三位加逗号的功能函数
2015/10/22 PHP
基础的prototype.js常用函数及其用法
2007/03/10 Javascript
JavaScript 学习技巧
2010/02/17 Javascript
jQuery 方法大全方便学习参考
2010/02/25 Javascript
Js四则运算函数代码
2012/07/21 Javascript
js实现带关闭按钮始终显示在网页最底部工具条的方法
2015/03/02 Javascript
JS实现文字放大效果的方法
2015/03/03 Javascript
JS实现文字掉落效果的方法
2015/05/06 Javascript
JS模式之简单的订阅者和发布者模式完整实例
2015/06/30 Javascript
Eclipse编辑jsp、js文件时卡死现象的解决办法汇总
2016/02/02 Javascript
JS Attribute属性操作详解
2016/05/19 Javascript
AngularJS基础 ng-model-options 指令简单示例
2016/08/02 Javascript
js代码实现下拉菜单【推荐】
2016/12/15 Javascript
JS实现的随机排序功能算法示例
2017/06/09 Javascript
vue2.0在table中实现全选和反选的示例代码
2017/11/04 Javascript
Vue自定义表单内容检查rules实例
2020/10/30 Javascript
详解Python的迭代器、生成器以及相关的itertools包
2015/04/02 Python
理解python中生成器用法
2017/12/20 Python
python去掉空白行的多种实现代码
2018/03/19 Python
如何用python写一个简单的词法分析器
2018/12/18 Python
pycharm远程开发项目的实现步骤
2019/01/20 Python
python学习开发mock接口
2019/04/28 Python
Django之创建引擎索引报错及解决详解
2019/07/17 Python
Python制作词云图代码实例
2019/09/09 Python
python 检测图片是否有马赛克
2020/12/01 Python
美国著名的婴儿学步鞋老品牌:Robeez
2016/08/20 全球购物
What is the purpose of Void class? Void类的作用是什么?
2016/10/31 面试题
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
经典导游欢迎词大全
2014/01/16 职场文书
学校党委副书记个人对照检查材料思想汇报
2014/09/28 职场文书
2015年汽车销售员工作总结
2015/07/24 职场文书