AJAX如何用於Web部件

原文地址:http://sharethispoint.com/archive/2006/11/15/Build-web-parts-with-ajax.aspx
如何在開發Web部件時使用ajax呢?我們將以一個樣子類似MOSS 2007中KPI和BDC Web部件的WebPart爲例來說明。如果你對ajax一點都不瞭解,推薦學習TerryLee的ajax入門系列。
ASP.net2.0有一個很酷的新特性叫作客戶端腳本回調。腳本回調主要使我們可以使用javascript調用服務器端程序中的方法,然後根據結果來做一些操作。這就使我們可以動態更新頁面的某一部分內容,正如將在我們下面的WebPart中看到的,而不必刷新整頁。關於在.net2.0中使用客戶端腳本回調,可以參考下面的文章地址(http://msdn.microsoft.com/msdnmag/issues/04/08/CuttingEdge/),其中做出了詳細的解釋。但是如何確切的將其使用與我們的代碼中,文章並沒有詳細介紹。事實上腳本回調特性是集成到.net中的,我們可以方便的拿來使用。
本示例中我們假設有這麼一個WebPart,它需要很長的時間才能顯示出內容。爲了解決這個問題,給用戶更好的體驗,我們決定讓render方法在WebPart剛剛載入時只輸出一個空的div標籤,然後我們通過ajax來替換div的內容,使其顯示出實際需要的內容。這樣,用戶就可以在頁面載入後在我們的WebPart完成內容載入前先看一看其他的內容。

下面我們就開始。

首先我們先創建一個新的WebPart項目。在我們的WebPart類中添加下面的命名空間。

using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

想要使.net知道我們的類要使用腳本回調,必須實現System.Web.UI.IcallbackEventHandler接口。

public class TreeViewRollUp:WebPart,ICallbackEventHandler

IcallBackEventHandler接口有兩個方法,public string GetCallbackResult()和 public void RaiseCallbackEvent(string eventArgs),稍後將對其進行介紹。
我們先定義兩個變量

private string datadiv; //用於保存div標籤名稱
private string ajaxdata; //用於保存ajax返回的數據 

datadiv變量保存了html中的我們打算輸出內容的div標籤的id。這個div標籤的名稱在一個WebPart實例中必須唯一。如果始終是一個固定名稱,那麼當我們在一個頁面中有兩個webpart的實例時它們有可能會替換對方的內容。
在webpart的RenderContents方法中加入下面的代碼:

protected override void RenderContents(HtmlTextWriter writer)
{
     
this.datadiv = this.ClientID + "content";  //使用WebPart實例的客戶端id 加上一個給定的名稱
     writer.Write("<div id=/"" + this.datadiv + "/"><img src=/"/_layouts/images/GEARS_AN.GIF/" width/"150/"></div>");
}

我們在最後一行的div標籤中加了一個進度條的小gif圖。這裏直接用了WSSv3中的圖片。

在OnLoad中粘貼如下代碼:

protected override void OnLoad(EventArgs e)
{
    
this.datadiv = this.ClientID + "content";
    
string js = Page.ClientScript.GetCallbackEventReference(this"'blah'""filldiv""'" + this.datadiv + "'"true);
     
string contentloader= "var ajaxcommands='';window.onload = ajaxloader; function ajaxloader() { eval(ajaxcommands); } function filldiv(arg, ctx){ var mydiv = document.getElementById(ctx); mydiv.innerHTML = arg;}";

      
if (Page.ClientScript.IsClientScriptBlockRegistered("contentloader"== false)
                Page.ClientScript.RegisterClientScriptBlock(Page.ClientScript.GetType(), 
"contentloader", contentloader, true);
            
            Page.ClientScript.RegisterStartupScript(
this.GetType(), "myloader"+this.ClientID, " ajaxcommands = ajaxcommands + /"" + js + ";/";"true);   //使用WebPart實例的客戶端id 加上一個給定的名稱作爲腳本的Key
       
base.OnLoad(e);
}

在該方法中註冊有兩塊不同的javascript塊 。
第一個字符串js的值來源於GetCallbackEventReference。GetCallbackEventReference方法用於返回執行回調服務器獲取數據的javascript。我們傳遞了:一個當前控件(webpart)的引用;“Blah”,作爲初始數據當回調啓動後將被傳遞到我們的服務器端組件;當回調結束後調用的Javascript方法的名字;我們的標記內容的div標籤的名字;異步開關設爲true這些必要的參數。
通過該方法生成的javascript類似於下面的樣子:

WebForm_DoCallback('ctl00$m$g_a010b3bd_1a68_40f9_b46b_f87050cf516f','blah',filldiv,'ctl00_m_g_a010b3bd_1a68_40f9_b46b_f87050cf516fcontents',null,true);

我們可以將這段javascript用於一個button的OnClick事件來啓動回調並填充div標籤。
在本例中,我們不希望用戶還要點擊什麼的才能繼續WebPart的載入。所以我們要在瀏覽器載入頁面時調用WebForm_DoCallback 方法。這是用contentloader字符串來實現的。Contentloader字符串定義了一個javascript變量, ajaxcommands,  用來保存我們準備執行的一些命令。同時,我們設置window.onload事件使其執行ajaxloader方法。當ajaxloader方法運行時將通過eval函數執行所有存在ajaxcommands變量中的命令。
爲什麼這麼寫呢?這是因爲如果我們在一個頁面裏有多於兩個的ajax webpart的實例時,每個實例都將會通過window.onload事件來載入數據,這樣問題就產生了。只有最後設定的事件處理(Event Handler)會被執行,並不是所有的設定都執行。爲此,我們打了一個擦邊球。在window.onload裏設定了一個command方法。每一個webpart僅僅擴充其WebForm_DoCallback到ajaxcommands 變量。這樣,起碼解決了本例中的問題。應該算得上一個好辦法吧。
最後,contentloader字符串也包括了filldiv方法,用於設定div中的回調所返回的html內容。

最後一步,在我們的類的OnLoad 方法中將腳本註冊到頁面中。我們只需要在一個頁面裏有一個contentloader javascript腳本。所以,我們在註冊前先判斷是否已經被頁面中其他的WebPart通過腳本管理器註冊了。

剩下的事兒就是實現IcallbackEventHandler接口所需要的兩個方法。
string ICallbackEventHandler.GetCallbackResult()
{
    
return this.ajaxdata;
}

void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
    
this.ajaxdata="Some crazy message here!<BR>"+this.ClientID;
}

RaiseCallbackEvent當客戶端回調啓動時將被調用。它是一個無返回值的方法,僅用於將GetCallbackResult方法需要的數據準備好。RaiseCallbackEvent方法是我們放置所有用於返回給webpart的render方法要顯示內容的相關代碼的地方。本例中我們只發送一條簡單的信息給客戶端。爲了區分不同的WebPart實例確實做了各自的工作,我們在信息後加上了各自的ClientID

趕快動手實踐一下吧,希望大家對使用客戶端回調已經入門了。  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章