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 相关文章推荐
参考:关于Javascript中实现暂停的几篇文章
Mar 04 Javascript
JavaScript 一行代码,轻松搞定浮动快捷留言-V2升级版
Apr 02 Javascript
js数值计算时使用parseInt进行数据类型转换(jquery)
Oct 07 Javascript
js简单实现表单中点击按钮动态增加输入框数量的方法
Aug 18 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
Aug 28 Javascript
JavaScript初学者必看“new”
Jun 12 Javascript
微信小程序之前台循环数据绑定
Aug 18 Javascript
bootstrap table方法之expandRow-collapseRow展开或关闭当前行数据
Aug 09 Javascript
小程序云开发教程如何使用云函数实现点赞功能
May 18 Javascript
JS判断数组是否包含某元素实现方法汇总
Jun 24 Javascript
ant design中upload组件上传大文件,显示进度条进度的实例
Oct 29 Javascript
react中hook介绍以及使用教程
Dec 11 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 5.3 下载时 VC9、VC6、Thread Safe、Non Thread Safe的区别分析
2011/03/28 PHP
基于php缓存的详解
2013/05/15 PHP
PHP实现批量清空删除指定文件夹所有内容的方法
2017/05/30 PHP
PHP的PDO连接讲解
2019/01/24 PHP
JavaScript的面向对象(二)
2006/11/09 Javascript
JavaScript 弹出窗体点击按钮返回选择数据的实现
2010/04/01 Javascript
url 编码 js url传参中文乱码解决方案
2010/04/11 Javascript
javascript 实用的文字链提示框效果
2010/06/30 Javascript
JavaScript 判断日期格式是否正确的实现代码
2011/07/04 Javascript
JS清除选择内容的方法
2015/01/29 Javascript
基于JS代码实现实时显示系统时间
2016/06/16 Javascript
BootStrapTable 单选及取值的实现方法
2017/01/10 Javascript
BootStrap Table复选框默认选中功能的实现代码(从数据库获取到对应的状态进行判断是否为选中状态)
2017/07/11 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
2017/09/26 Javascript
判断div滑动到底部的scroll实例代码
2017/11/15 Javascript
vue+canvas实现炫酷时钟效果的倒计时插件(已发布到npm的vue2插件,开箱即用)
2018/11/05 Javascript
nodejs读取图片返回给浏览器显示
2019/07/25 NodeJs
layer关闭弹出窗口触发表单提交问题的处理方法
2019/09/25 Javascript
在Python中使用mongoengine操作MongoDB教程
2015/04/24 Python
python3.6+opencv3.4实现鼠标交互查看图片像素
2018/02/26 Python
Python基于property实现类的特性操作示例
2018/06/15 Python
关于Pycharm无法debug问题的总结
2019/01/19 Python
解决python3中的requests解析中文页面出现乱码问题
2019/04/19 Python
python中使用ctypes调用so传参设置遇到的问题及解决方法
2019/06/19 Python
一篇文章了解Python中常见的序列化操作
2019/06/20 Python
Python实现的企业粉丝抽奖功能示例
2019/07/26 Python
Python 用turtle实现用正方形画圆的例子
2019/11/21 Python
django xadmin action兼容自定义model权限教程
2020/03/30 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
2020/06/10 Python
python中@contextmanager实例用法
2021/02/07 Python
css3 transform过渡抖动问题解决
2020/10/23 HTML / CSS
秋季运动会广播稿大全
2014/02/17 职场文书
挂牌仪式策划方案
2014/05/18 职场文书
大学生安全责任书
2014/07/25 职场文书
学生逃课万能检讨书2000字
2015/02/17 职场文书
python opencv通过4坐标剪裁图片
2021/06/05 Python