Ext.Net通過DirectEvents進行服務器端異步的事件處理。【Ext.Net學習筆記】02:Ext.Net用法概覽、Ext.Net MessageBus用法、Ext.Net布局 中已經簡單的介紹了DirectEvents,今天將詳細的介紹一下DirectEvents。
DirectEvents異步執行服務器端事件
我們首先來看一下Ext.Net DirectEvents的一個最簡單用法,通過點擊按鈕觸發服務器端的事件處理方法,並在前台彈出一個提示框。
<ext:Window runat="server" ID="win1" Title="Ext.Net DirectEvents" Width="300" Height="200"> <Buttons> <ext:Button runat="server" ID="btnOK" Text="確定" Icon="Accept" OnDirectClick="btnOK_DirectClick"> </ext:Button> </Buttons> </ext:Window>
這里添加了OnDirectEvents事件,它的一個簡寫方式,完整的寫法如下:
<ext:Button runat="server" ID="btnOK" Text="確定" Icon="Accept"> <DirectEvents> <Click OnEvent="btnOK_DirectClick"></Click> </DirectEvents> </ext:Button>
事件處理方法如下:
protected void btnOK_DirectClick(object sender, Ext.Net.DirectEventArgs e) { X.MessageBox.Alert("提示", "按鈕被點擊").Show(); }
編譯代碼並刷新頁面,點擊按鈕,我們會看到如下效果:

顯示Mask遮罩層
上面的代碼已經演示了如何使用DirectEvents執行服務器端的事件,DirectEvents是通過異步方式執行服務器端代碼的,那么,我們通常會希望在執行的時候客戶端顯示一個遮罩層,阻止用戶進行其他操作,這點Ext.Net已經為我們想到了。
<ext:Button runat="server" ID="btnOK" Text="確定" Icon="Accept"> <DirectEvents> <Click OnEvent="btnOK_DirectClick"> <EventMask ShowMask="true" Msg="正在處理..."></EventMask> </Click> </DirectEvents> </ext:Button>
然后我們在服務器端事件處理方法中讓程序休息一下:
protected void btnOK_DirectClick(object sender, Ext.Net.DirectEventArgs e) { System.Threading.Thread.Sleep(3000);//將當期線程掛起3000毫秒,即3秒 X.MessageBox.Alert("提示", "按鈕被點擊").Show(); }
這樣當我們再點擊按鈕的時候,會看到如下效果:

為事件添加自定義參數
Ext.Net DirectEvents 還允許我們為事件添加自定義參數。
<ext:Button runat="server" ID="btnOK" Text="確定" Icon="Accept"> <DirectEvents> <Click OnEvent="btnOK_DirectClick"> <EventMask ShowMask="true" Msg="正在處理..."></EventMask> <ExtraParams> <ext:Parameter Name="name" Value="btnOK"></ext:Parameter> </ExtraParams> </Click> </DirectEvents> </ext:Button>
在這里,我們將傳給處理方法一個名稱為name的參數,看一下服務器端的處理:
protected void btnOK_DirectClick(object sender, Ext.Net.DirectEventArgs e) { System.Threading.Thread.Sleep(3000); string btnName = e.ExtraParams["name"]; X.MessageBox.Alert("提示", btnName + "被點擊").Show(); }

在服務器端,我們通過e.ExtraParams來訪問這些參數。
處理服務器返回的數據
Ext.Net DirectEvents 可以通過添加一個客戶端回調方法來處理服務器返回的數據。
<ext:Button runat="server" ID="btnOK" Text="確定" Icon="Accept"> <DirectEvents> <Click OnEvent="btnOK_DirectClick" Success="fnSuccess"> <EventMask ShowMask="true" Msg="正在處理..."></EventMask> <ExtraParams> <ext:Parameter Name="name" Value="btnOK"></ext:Parameter> </ExtraParams> </Click> </DirectEvents> </ext:Button>
在配置中添加一個success配置,表示在執行成功以后調用fnSuccess方法,fnSuccess方法的定義如下:
function fnSuccess(response, result) { alert(result.extraParamsResponse.data); }
接下來看看服務器端如何返回數據的:
protected void btnOK_DirectClick(object sender, Ext.Net.DirectEventArgs e) { e.ExtraParamsResponse.Add(new Ext.Net.Parameter("data", "abc")); }
通過這樣的處理,我們就可以從服務器返回數據,並在客戶端通過js代碼進行處理了,代碼效果如下。

confirmation配置
confirmation配置是用來在觸發事件之前進行提示,有用戶決定是否提交服務器進行處理的。
它的用法很簡單,卻很實用。
<ext:Button runat="server" ID="btnOK" Text="確定" Icon="Accept"> <DirectEvents> <Click OnEvent="btnOK_DirectClick" Success="fnSuccess"> <EventMask ShowMask="true" Msg="正在處理..."></EventMask> <ExtraParams> <ext:Parameter Name="name" Value="btnOK"></ext:Parameter> </ExtraParams> <Confirmation ConfirmRequest="true" Title="提示" Message="確定要提交服務器嗎?"> </Confirmation> </Click> </DirectEvents> </ext:Button>
不需要進行多余的代碼處理,只要這兩行配置就可以完成在出發時間前進行提醒:

Ext.Net DirectEvents除了能夠在Ext.Net中很方便的使用之外,還可以結合Asp.Net控件、HTML控件進行使用。
在ASP.NET控件上面使用DirectEvents
我們在ASP.NET中實現無刷新的頁面請求的時候,通常會用到UpdatePanel,現在Ext.Net為我們提供了另外一種渠道:通過DirectEvents來實現無刷新的頁面請求。
<asp:Label runat="server">名稱</asp:Label> <asp:TextBox runat="server" ID="txtName" /> <asp:Button runat="server" ID="btnOK" Text="確定" />
首先,我在頁面放上一個文本框和按鈕,當我們點擊確定按鈕的時候,希望在后台能夠取到文本框的值。
接下來才是見證奇跡的時刻:
<ext:ResourceManager runat="server"> <CustomDirectEvents> <ext:DirectEvent Target="btnOK" OnEvent="btnOK_DirectClick"> </ext:DirectEvent> </CustomDirectEvents> </ext:ResourceManager>
我們來配置一個DirectEvent,通過這個DirectEvent來執行服務器端的事件方法,我們來看看服務器端的代碼:
protected void btnOK_DirectClick(object sender, Ext.Net.DirectEventArgs e) { string name = this.txtName.Text; X.MessageBox.Alert("提示", "按鈕被點擊,輸入框的值為:" + name).Show(); }
通過這段代碼,我們會取到文本框輸入的值,並在客戶端彈出一個提示框,並且這個過程是無刷新的。效果如下:

在HTML控件上面使用DirectEvents
ASP.NET控件可以用,HTML控件同樣可以使用DirectEvents(真的是萬能哦)。來看看如何在HTML按鈕中使用DirectEvents吧,為了演示,我在上面頁面中的按鈕替換成HTML按鈕:
<input type="button" value="確定" id="htmlBtn" />
然后再ResourceManager節點中配置:
<ext:ResourceManager runat="server"> <CustomDirectEvents> <ext:DirectEvent Target="htmlBtn" OnEvent="btnOK_DirectClick"> </ext:DirectEvent> </CustomDirectEvents> </ext:ResourceManager>
這樣就完成了。當我們點擊這個HTML按鈕的時候,你會看到和上面一樣的效果。
DirectEvents調用WebService
DirectEvents除了可以異步執行頁面中的事件,還可以遠程調用WebService。
新建一個Web服務文件,文件名為ExtNetService 。

[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] public class ExtNetService : System.Web.Services.WebService { [WebMethod] public DirectResponse GetServerTimeWindow() { new Window("Server time", Icon.Time) { ID = "MyWindow", Html = DateTime.Now.ToString() }.Render(); return new DirectResponse(); } }
這是我們定義的Service程序,然后來配置DirectEvents:
<ext:ResourceManager runat="server"> <CustomDirectEvents> <ext:DirectEvent Target="htmlBtn" Url="ExtNetService.asmx/GetServerTimeWindow" Method="POST" Type="Load"> </ext:DirectEvent> </CustomDirectEvents> </ext:ResourceManager>
然后點擊htmlBtn按鈕,這個時候會打開一個來自服務器端的小窗口:

注意這個例子,如果你去跟蹤一下請求過程,你會發現這里其實是遠程的調用了這個WebService,這里和一般的URL請求是一樣的,因此DirectEvents一樣可以調用一般處理程序(.ashx)
DirectEvents調用一般處理程序(.ashx)
既然可以遠程調用一個WebService,那么遠程調用一個一般處理程序肯定是沒有問題的。
首先來看看一般處理程序的代碼:
public class ServerTimeHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { new Window("Server time", Icon.Time) { ID = "MyWindow", Html = DateTime.Now.ToString() }.Render(); new DirectResponse().Return(); } public bool IsReusable { get { return false; } } }
然后,我們修改一下DirectEvents配置,將剛才的WebService鏈接調整一下,其他的不動:
<ext:ResourceManager runat="server"> <CustomDirectEvents> <ext:DirectEvent Target="htmlBtn" Url="ServerTimeHandler.ashx" Method="POST" Type="Load"> </ext:DirectEvent> </CustomDirectEvents> </ext:ResourceManager>
運行程序以后,你會看到與調用WebService一樣的效果。
DirectEvents動態生成Ext.Net控件
剛才在演示調用WebService和一般處理程序的時候,已經看到了如何生成Ext.Net控件,再看一下代碼:
new Window("Server time", Icon.Time) { ID = "MyWindow", Html = DateTime.Now.ToString() }.Render(); return new DirectResponse();
注意,如果要Window顯示出來,就必須調用Render方法。
DirectEvents更新ASP.NET控件
我們知道UpdatePanel的更新過程:首先向服務器發送一個異步請求,然后服務器進行重繪,將控件重新生成HTML代碼,並返回給客戶端,最后,由UpdatePanel客戶端JS決定如何替換,達到更新頁面的效果。
那么,通過DirectEvents一樣可以更新ASP.NET控件。
我們回到第一個例子,通過點擊按鈕來得到文本框的值。我們在例子中已經完成了取值的過程,接下來我們希望為文本框賦值,代碼如下:
protected void btnOK_DirectClick(object sender, Ext.Net.DirectEventArgs e) { this.txtName.Text = "http://www.cnblogs.com/yc-755909659/"; this.txtName.Update(); }
除了賦值以外,我們還要顯示的調用Update方法,不然就會賦值失敗。
前面看到了DirectEvents方便調用服務器端方法、DirectEvents調用WebService方法的使用方法,下面我們來看看DirectMethods,這家伙可比DirectEvents更加靈活了,它可以像調用JS方法一樣來異步調用服務器端的方法。
使用DirectMethods在JS中調用C#方法
我承認,這個標題有點噱頭,其實應該是通過DirectMethods,在JS中通過異步調用的方式執行服務器端的方法。
來看一個例子吧:
[DirectMethod] public void AddToServerTime(int hours) { var date = DateTime.Now.Add(new TimeSpan(hours, 0, 0)); this.myLabel.Text = date.ToString(); }
這是一個aspx頁面中的服務器端方法,為了能夠在JS中來調用,必須添加DirectMethod特性。
接下來讓我們看看JS調用:
<script type="text/javascript"> function fnUpdate() { App.direct.AddToServerTime(3); } </script>
就是這句話,它被定義在命名空間App.direct下,當然,這個命名空間是可以修改的,我會在接下來告訴你怎么修改。
然后添加一個按鈕,在點擊按鈕的時候來執行fnUpdate方法。
<ext:Window runat="server" ID="win1" Width="300" Height="200" Title="DirectMethods"> <Items> <ext:Label runat="server" ID="myLabel"></ext:Label> </Items> <Buttons> <ext:Button runat="server" ID="btnUpdate" Text="更新" Handler="fnUpdate()"></ext:Button> </Buttons> </ext:Window>
我們這里使用的是Ext.Net按鈕,你還可以使用Asp.Net按鈕,或者是Html按鈕,不再細說。
然后我們編譯代碼,刷新頁面,點擊這個按鈕吧,你會看到window中的顯示效果如下:

設置DirectMethods的命名空間
默認情況下,DirectMethods的命名空間是App.direct,我們可以通過N中方法來改變這個默認的命名空間:
在Ext.Net全局配置中更改
<extnet theme="Neptune" directMethodNamespace="MyApp.DirectMethods" />
這種更改方式是在web.config中完成的,如果你不知道怎么在web.config中添加extnet配置節點,那么你肯定是沒有看第一篇筆記,去看看吧>>【Ext.Net學習筆記】01:在ASP.NET WebForm中使用Ext.Net
這種更改方式將對所有頁面有效。
在Ext.Net ResourceManager配置中更改
<ext:ResourceManager runat="server" DirectMethodNamespace="MyApp.DirectMethods"> </ext:ResourceManager>
這種更改方式是在頁面中完成的,它只對當前頁面有效,當然了,它肯定是要覆蓋全局的設置的。
在DirectMethod特性構造函數中更改
這是最后一種設置方式,它更加靈活,它可以更改某一個方法的命名空間。
[DirectMethod(Namespace = "MyApp.DirectMethods")] public void AddToServerTime(int hours) { var date = DateTime.Now.Add(new TimeSpan(hours, 0, 0)); this.myLabel.Text = date.ToString(); }
這種方法只對設置的方法有用,它將會覆蓋頁面和全局的配置。
添加回調方法
前面提到過,Ext.Net DirectMethods和DirectEvents類似,都是通過JS實現的異步調用,因此,如果要處理服務器端的執行結構,就必須在JS中添加相應的回調方法。
function fnUpdate() { MyApp.DirectMethods.AddToServerTime(5, { success: onSuccess, failure: onFailure, eventMask: { showMask: true } }); } function onSuccess() { alert("成功"); } function onFailure() { alert("失敗"); }
在這段代碼中,我們在調用DirectMethod方法的時候添加了一些配置,包括執行成功和失敗的回調方法,以及來顯示一個遮罩層,效果如下:

同步執行服務器端方法
一般情況下我們都是采用異步的方式來執行服務器端的方法,這樣能夠獲得更好的用戶體驗,當然,如果你有怪癖,希望能夠通過同步的方式來執行服務器端方法,Ext.Net DirectMethods也是支持的。
[DirectMethod(Namespace = "MyApp.DirectMethods", Async = false)] public void AddToServerTime(int hours) { string text = this.btnUpdate.Text; var date = DateTime.Now.Add(new TimeSpan(hours, 0, 0)); this.myLabel.Text = text + date.ToString(); }
很簡單的一個設置,在DirectMethod構造函數中配置一下就可以了。
鄭重的提醒,盡量少用同步的請求,這樣會造成瀏覽器假死的現象,至於什么是瀏覽器假死,你去試試搶一下春運時候的火車票就知道了
提升性能:調用靜態方法
先來說說非靜態方法,在執行非靜態方法的時候,Ext.Net會提交更多的數據,使我們可以訪問頁面中的控件這在處理頁面相關內容時候非常有用,但是當我們只是想去執行一個處理過程,而與頁面無關的時候,我們就可以通過執行靜態方法來提升性能。
在靜態方法中,我們不能訪問頁面的Form數據,不能直接訪問Request、Response等數據(可以通過HttpContext.Current來訪問),好處是在請求的時候,Ext.Net不會將頁面數據提交給服務器,大大減少了數據傳輸和服務器執行的時間。
[DirectMethod(Namespace = "MyApp.DirectMethods")] public static string AddToServerTime(int hours) { var date = DateTime.Now.Add(new TimeSpan(hours, 0, 0)); return date.ToString(); }
這是我們剛才的方法,現在把它改成了靜態方法。JS的調用基本沒有改變,只不過我們需要在JS中來更新控件的顯示了。
function fnUpdate() { MyApp.DirectMethods.AddToServerTime(5, { success: onSuccess, failure: onFailure, eventMask: { showMask: true } }); } function onSuccess(result) { App.myLabel.setText(result); }
我們需要對onSuccess回調方法進行修改,在它接收到執行結果之后更新界面顯示。
Ext.net.DirectMethod.request調用WebService
DirectMethods不能直接訪問WebService,但可以通過Ext.net.DirectMethod.request來請求WebService,實現類似於頁面后台方法的效果。
var showRelativeServerTime = function () { Ext.net.DirectMethod.request({ url: "EchoService.asmx/Echo", cleanRequest: true, params: { something: "Hello world!" }, success: function (result) { alert(Ext.DomQuery.selectValue("string", result, "")); } }); }
這是方法的調用過程,不再演示了。
附加說明:這種方法受用於一切WebService、一般處理程序、MVC等通過url訪問的東東,非常好用。
異常處理
這是一個大問題,一般情況下,如果你想偷懶,Ext.Net默認已經幫我們進行了異常處理。當然,如果你想更友好的給用戶進行提示,那就來手動處理吧。
[DirectMethod] public static int Divide(int number1, int number2) { if (number2 == 0) { ResourceManager.AjaxSuccess = false; ResourceManager.AjaxErrorMessage = "number2 can't be zero!"; return 0; } return number1 / number2; }
這樣一來,我們手動的判斷是否執行成功。當然,你還可以這樣寫:
[DirectMethod] public static void DoSomething() { try { // call through to your business logic layer } catch (Exception e) { ResourceManager.AjaxSuccess = false; ResourceManager.AjaxErrorMessage = GetFriendlyMessage(e); } }
That's All 。
來源:
Ext.Net學習筆記05:Ext.Net DirectEvents用法詳解
Ext.Net學習筆記06:Ext.Net DirectEvents用方補充
Ext.Net學習筆記07:Ext.Net DirectMethods用法詳解
