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 相关文章推荐
为EasyUI的Tab标签添加右键菜单的方法
Jul 14 Javascript
location.href用法总结(最主要的)
Dec 27 Javascript
JavaScript字符串对象substr方法入门实例(用于截取字符串)
Oct 16 Javascript
JavaScript中逗号运算符介绍及使用示例
Mar 13 Javascript
谈谈对JavaScript原生拖放的深入理解
Sep 20 Javascript
浅谈jQuery绑定事件会叠加的解决方法和心得总结
Oct 26 Javascript
js中toString()和String()区别详解
Mar 23 Javascript
Vue组件选项props实例详解
Aug 18 Javascript
原生js调用json方法总结
Feb 22 Javascript
学习Vue组件实例
Apr 28 Javascript
JavaScript DOM元素常见操作详解【添加、删除、修改等】
May 09 Javascript
JS相册图片抖动放大展示效果的示例代码
Jan 29 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接口中interface存在的意义
2013/06/27 PHP
CodeIgniter上传图片成功的全部过程分享
2013/08/12 PHP
jscript之List Excel Color Values
2007/06/13 Javascript
页面回到顶部的三种实现(锚标记,js)
2012/10/01 Javascript
IE8下Jquery获取select选中的值post到后台报错问题
2014/07/02 Javascript
vue的props实现子组件随父组件一起变化
2016/10/27 Javascript
Vue自定义指令详解
2017/07/28 Javascript
AngularJS 控制器 controller的详解
2017/10/17 Javascript
解决vue项目中type=”file“ change事件只执行一次的问题
2018/05/16 Javascript
jQuery实现的中英文切换功能示例
2019/01/11 jQuery
angularjs模态框的使用代码实例
2019/12/20 Javascript
es6中new.target的作用和使用场景简单示例分析
2020/03/14 Javascript
[00:10]DOTA2全国高校联赛 以DOTA2会友
2018/05/30 DOTA
python去除文件中空格、Tab及回车的方法
2016/04/12 Python
python的pdb调试命令的命令整理及实例
2017/07/12 Python
python的exec、eval使用分析
2017/12/11 Python
python中的字典操作及字典函数
2018/01/03 Python
python实现感知器算法(批处理)
2019/01/18 Python
Python3 tkinter 实现文件读取及保存功能
2019/09/12 Python
Django2 连接MySQL及model测试实例分析
2019/12/10 Python
Python的赋值、深拷贝与浅拷贝的区别详解
2020/02/12 Python
了解一下python内建模块collections
2020/09/07 Python
python温度转换华氏温度实现代码
2020/12/06 Python
python通过cython加密代码
2020/12/11 Python
雅诗兰黛旗下专业男士保养领导品牌:Lab Series
2017/05/15 全球购物
面向对象编程OOP的优点
2013/01/22 面试题
中间件的定义
2016/08/09 面试题
采购主管的岗位职责
2013/12/17 职场文书
幼儿园义卖活动方案
2014/01/17 职场文书
中药学专业毕业生推荐信
2014/07/10 职场文书
趣味运动会广播稿
2014/09/13 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
义诊活动通知
2015/04/24 职场文书
python中print格式化输出的问题
2021/04/16 Python
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
2021/04/25 Python
Python获取江苏疫情实时数据及爬虫分析
2021/08/02 Python