DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> SharePoint 客戶端對象模型 (一) ECMA Script
SharePoint 客戶端對象模型 (一) ECMA Script
編輯:關於JavaScript     
所謂的客戶端對象模型就是調用了背後的WCF服務來提供數據,為了減輕數據的訪問量數據包使用JSON,我們還可以看到對象模型的設計也加入了諸多對於減輕數據訪問量的考量。技術上沒有什麼新意,你要願意,在SharePoint2007裡面也可以實現類似的功能,當然在使用上方便了我們不少

image 
三種使用客戶端模型的.NET托管、ECMA腳本,SilverLightClient.

image

本文講闡述如何使用.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,後續裡如果有重要的也會逐步加進來。

image

裡面的鏈接會調用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。

image

演示結果如下:

在文本框裡輸入列表名字後,點擊"Create List”按鈕,生成列表後會在右上角提示“List test1 created”,本例中使用annoucement做為列表類型。

image

源代碼如下:
復制代碼 代碼如下:
<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)

image

代碼非常的直接,只說明一個點,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>

image

image

做了一段對控件顯示的控制,選擇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對象進行操作。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved