[原創] MVC3 Web.Helpers – WebGrid Ajax 及查詢綁定
本文只代表作者在一定階段的認識與理解。
一、寫作前提
Microsoft Asp.Net MVC3 的Bate version Release有些日子了,園子里關于3所帶的新功能、新組件及新方法使用的文章就出了很多,對其好壞我不做評價,但肯定的是,這些文章讓我受益匪淺,感受良多。之前做過Asp.Net MVC Version 1的項目,Version1里面的很多功能都比較不完善,但開發出來的效果還是可以令人滿意的,特別是在加載速度、代碼修改和更新部署上有特別的優勢。今天我們將就3的Bate Version所帶的WebGrid進行以下兩點描述:1.查詢條件的綁定,2. WebGrid Sorting Ajax的實現,本文在代碼編寫上使用的是MVC3新提供的Razor方式(優點:因為它及大的簡單了代碼的書寫;缺點:當前版本沒有智能代碼提示),可參考Asp.Net MVC3 Razor
二、本文內容
- WebGrid的使用
- WebGrid Sorting(排序) Ajax的實現
- WebGrid Search Conditions(查詢條件)的綁定
- 總結
- 代碼下載 (下載)
三、MVC3 WebGrid 小試
1. WebGrid的使用
WebGrid的使用園子里已經有很多相關的文章了,也不是我們的重點,在這里我們只提供一個示例,為下面代碼的描述作比較。
Action:
1 public ActionResult Gridview()
2 {
3 DALDataContext da = new DALDataContext();
4 var result =da.T_STUDENTs.ToList();
5 this.ViewData.Model = result;
6 return View();
7 }View:(如果對其中的屬性不明白,請參考下面四中的內容。
1 @using MVC3Tutorial;
2 @model List<T_STUDENT>
3 @{
4 View.Title = "Gridview";
5 Layout = "~/Views/Shared/_Layout.cshtml";
6 }
7
8 @{
9 var grid = new WebGrid(source:Model,
10 fieldNamePrefix:"grid_",
11 defaultSort: "StudentName",
12 canPage:true,
13 canSort:true,
14 ajaxUpdateContainerId:"DivGrid",
15 pageFieldName:"paging",
16 sortFieldName:"sortField",
17 rowsPerPage:10);
18
19 <div id="DivGrid">
20 @grid.GetHtml(
21 columns:grid.Columns(
22 grid.Column("StudentID", "Student ID"),
23 grid.Column("StudentName", "Student Name"),
24 grid.Column("StudentCode", "Student Code"),
25 grid.Column("Sex", "Sex"),
26 grid.Column("NRICPassport", "NRIC/Passport No.")
27 )
28 )
29 </div>
30 <h2>
31 Page Count:
32 @Html.Encode(grid.PageCount)
33 <br/>
34 Total Record:
35 @Html.Encode(grid.TotalRowCount)
36 </h2>
37 @Html.Encode(grid.FieldNamePrefix)
38 }
上面我們就實現了對WebGrid的使用,得到結果如下:
2. WebGrid Sorting(排序) Ajax的實現
我們看,在上面的View代碼中黃色背景表示的是創建WebGrid對象實例,其中有這樣一行ajaxUpdateContainerId:"DivGrid",他表示的是當WebGrid發生AjaxUpdate事件后,將更新后內容顯示到指定的元素中。在我們示例中,我們指定的是一個Div對象。也就是說我們期望得到的結果是,當我們點擊標題行的列進行排序后,應該把排序后的新內容放到這個Div中,并且是Ajax操作。但是在實際操作中,瀏覽器會提示如下信息:
為什么他會提示這樣的信息呢?我們點擊上面的結果,查看源代碼,有如下行:
我們可以看到,他生成的是一個JQuery的操作方式,所以我們必須引用JQuery的類庫,如下(本下在_Layout.cshtml中加載的):
1 <head>
2 <title>@View.Title</title>
3 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
4 <script language="javascript" src="@Url.Content("~/Scripts/jquery-1.4.1.min.js")"></script>
5 </head>當你再次運行時,你就會發現,這時他已經是局部刷新了。
3. WebGrid Search Conditions(查詢條件)的綁定
我們通常使用Grid的時候肯定不是直接使用的,比如說查詢頁面,常常有許多查詢條件的,我們都知道MVC是沒有ViewState的,當我們點擊sorting的時候,輸入的查詢條件就可能會被刷新掉,所以將會影響我們的查詢結果,如何解決這個問題呢?
現將View代碼修改如下:
1 @using MVC3Tutorial;
2 @model List<T_STUDENT>
3 @{
4 View.Title = "Gridview";
5 Layout = "~/Views/Shared/_Layout.cshtml";
6 }
7
8 @using(Ajax.BeginForm("Gridview","Home",new AjaxOptions{ UpdateTargetId="DivGrid"}) )
9 {
10 IDictionary<string, string> searchConditions = new Dictionary<string, string>();
11
12 if(TempData["SearchConditions"]!=null)
13 {
14 searchConditions = TempData["SearchConditions"] as Dictionary<string, string>;
15 }
16
17 this.TempData["SearchConditions"]=searchConditions;
18
19 string studentName = searchConditions.Keys.Contains("StudentName")?searchConditions["StudentName"]:string.Empty;
20 string nricPassport = searchConditions.Keys.Contains("nricPassport")?searchConditions["nricPassport"]:string.Empty;
21
22 <div>
23 @Html.Encode("Student Name: ")
24 </div>
25 @Html.TextBox("StudentName",@studentName)
26 <div>
27 @Html.Encode("NRIC/Passport No.: ")
28 </div>
29 @Html.TextBox("nricPassport",@nricPassport)
30 <br/>
31 <input type="Submit" Text="Search"/>
32
33 var grid = new WebGrid(source:Model,
34 fieldNamePrefix:"grid_",
35 defaultSort: "StudentName",
36 canPage:true,
37 canSort:true,
38 ajaxUpdateContainerId:"DivGrid",
39 pageFieldName:"paging",
40 sortFieldName:"sortField",
41 rowsPerPage:10);
42
43 <div id="DivGrid">
44 @grid.GetHtml(
45 columns:grid.Columns(
46 grid.Column("StudentID", "Student ID"),
47 grid.Column("StudentName", "Student Name"),
48 grid.Column("StudentCode", "Student Code"),
49 grid.Column("Sex", "Sex"),
50 grid.Column("NRICPassport", "NRIC/Passport No.")
51 )
52 )
53 </div>
54 <h2>
55 Page Count:
56 @Html.Encode(grid.PageCount)
57 <br/>
58 Total Record:
59 @Html.Encode(grid.TotalRowCount)
60 </h2>
61 @Html.Encode(grid.FieldNamePrefix)
62 }
現在我們多了兩個查詢條件,叫Student Name,NRIC/Password No.,如下圖所示:
那么當我們點擊Sorting的時候如何它才能保持現有的查詢條件不變呢?我所采取的策略是使用TempData保存現有的查詢條件,所以我們就需要在Action中獲取查詢條件并將其放放TempData中,當Action返回時,我們在view中把現有的TempData再次的進行綁定,因為WebGrid的Sorting他請求的是一個URL,而不是提交事件,所以當點擊Sorting的時候,他并不會收集form中的對象,但是因為之前的一次查詢,我們將查詢條件存入了TempData中,所以現在我們可以從TempData中取出查詢條件,Action代碼修改如下:
1 public ActionResult Gridview()
2 {
3 IDictionary<string, string> searchConditions = new Dictionary<string, string>();
4
5 if (this.Request.Form.AllKeys.Length > 0)
6 {
7 searchConditions.Add("StudentName", Request["StudentName"]);
8 searchConditions.Add("nricPassport", Request["nricPassport"]);
9 }
10 else
11 {
12 object values = null;
13
14 if (this.TempData.TryGetValue("SearchConditions", out values))
15 {
16 searchConditions = values as Dictionary<string, string>;
17 }
18 }
19
20 this.TempData["SearchConditions"] = searchConditions;
21
22 string studentName = GetSearchConditionValue(searchConditions, "StudentName");
23 string nric = GetSearchConditionValue(searchConditions, "nricPassport");
24
25 DALDataContext da = new DALDataContext();
26 var result = (from s in da.T_STUDENTs
27 where (string.IsNullOrEmpty(studentName) || s.StudentName.StartsWith(studentName))
28 && (string.IsNullOrEmpty(nric) || s.NRICPassport.StartsWith(nric))
29 select s).ToList();
30 this.ViewData.Model = result;
31 return View();
32 }
33
34 private static string GetSearchConditionValue(IDictionary<string, string> searchConditions, string key)
35 {
36 string tempValue = string.Empty;
37
38 if (searchConditions != null && searchConditions.Keys.Contains("StudentName"))
39 {
40 searchConditions.TryGetValue(key, out tempValue);
41 }
42 return tempValue;
43 }上在的Action就是實現了這樣的一件事情,第一次提交的時候把查詢條件給TempData,然后在后面的非Submit事件中,使用已經保存在TempData中的查詢條件。這樣我們就實現了查詢條件與MVC WebGrid的綁定。雖然這樣的方案并不是十分的完美,但也是其解決方案之一,如果有那個博友有更好的解決方案,還請拍磚斧正。
上面我們已經講完了本文主要的3點內容,但是WebGrid中還有一些其它的參數,很多文章都有介紹,在這里我們再多做一次補充,以方便博友閱讀此文。
但是通過上文的實例,我們個人覺的他有一些不足,因為他在取Data的時候,一次性的返回所有需要的 Data,然后再將其返回到我們的Action中,這樣必然增加了Application與Database之間數據的通信量,如果數據量很大的時候必然也會給網絡帶來很大的壓力,如果我們在Database里就把分頁的數據直接返回,那么將大大減少數據傳輸量(數據庫分頁也會比較快)。
四、方法及參數說明
WebGrid有兩個構造函數,在他的構造函數中所需要的一些參數正是用來指定所創建出來的WebGrid生成的HTML是否具備如分頁、排序等功能。主要參數如下:
構造函數參數解釋:1 // Methods
2 public WebGrid([Dynamic(new bool[] { false, true })] IEnumerable<object> source, [Optional, DefaultParameterValue(null)] IEnumerable<string> columnNames, [Optional, DefaultParameterValue(null)] string defaultSort, [Optional, DefaultParameterValue(10)] int rowsPerPage, [Optional, DefaultParameterValue(true)] bool canPage, [Optional, DefaultParameterValue(true)] bool canSort, [Optional, DefaultParameterValue(null)] string ajaxUpdateContainerId, [Optional, DefaultParameterValue(null)] string fieldNamePrefix, [Optional, DefaultParameterValue(null)] string pageFieldName, [Optional, DefaultParameterValue(null)] string selectionFieldName, [Optional, DefaultParameterValue(null)] string sortFieldName, [Optional, DefaultParameterValue(null)] string sortDirectionFieldName);
3 internal WebGrid(HttpContextBase context, [Dynamic(new bool[] { false, true })] IEnumerable<object> source, [Optional, DefaultParameterValue(null)] IEnumerable<string> columnNames, [Optional, DefaultParameterValue(null)] string defaultSort, [Optional, DefaultParameterValue(10)] int rowsPerPage, [Optional, DefaultParameterValue(true)] bool canPage, [Optional, DefaultParameterValue(true)] bool canSort, [Optional, DefaultParameterValue(null)] string ajaxUpdateContainerId, [Optional, DefaultParameterValue(null)] string fieldNamePrefix, [Optional, DefaultParameterValue(null)] string pageFieldName, [Optional, DefaultParameterValue(null)] string selectionFieldName, [Optional, DefaultParameterValue(null)] string sortFieldName, [Optional, DefaultParameterValue(null)] string sortDirectionFieldName);
4
5 // Properties
6 public string AjaxUpdateContainerId { get; }
7 public IEnumerable<string> ColumnNames { get; }
8 [Dynamic(new bool[] { false, true })]
9 public IEnumerable<object> DataSource { [return: Dynamic(new bool[] { false, true })] get; }
10 private Type ElementType { get; }
11 public string FieldNamePrefix { get; }
12 public bool HasSelection { get; }
13 private HttpContextBase HttpContext { get; }
14 public int PageCount { get; }
15 public string PageFieldName { get; }
16 public int PageIndex { get; set; }
17 private NameValueCollection QueryString { get; }
18 public IList<WebGridRow> Rows { get; }
19 public int RowsPerPage { get; }
20 public int SelectedIndex { get; set; }
21 public WebGridRow SelectedRow { get; }
22 public string SelectionFieldName { get; }
23 public string SortColumn { get; set; }
24 public SortDirection SortDirection { get; set; }
25 public string SortDirectionFieldName { get; }
26 public string SortFieldName { get; }
27 public int TotalRowCount { get; }
1 Source 此參數在WebGrid的構造函數中,為WebGrid指定數據源,如本例中的Model,即List<T_STUDENT> 2 columnNames 在source中的字段的集合,如: columnNames:new []{"StudentID","StudentName"},指定要顯示的列 3 defaultSort 指定默認排序的字段名 4 rowsPerPage 指定每一頁顯示多少行 5 canPage 是否允許分頁,默認為true 6 canSort 是否允許排序,默認為true 7 ajaxUpdateContainerId 指定到對象的ID,例如本例中的DivGrid,當產生Ajax事件后,將更新后的數據show在這個ID的容器中。 8 fieldNamePrefix 給WebGrid產生的字符串加前綴,比如說在沒有加前綴的時候Sorting鏈接為“/Home/Gridview?sort=StudentID&sortdir=ASC”,為其加完前綴grid_后為,字符鏈接“/Home/Gridview?grid_sort=StudentID&grid_sortdir=ASC”,即WebGrid中所有的參數都加上其前綴 9 pageFieldName 自定義分頁QueryString的參數名稱,比如說pageFieldName=”paging”,再加上面fieldNamePrefix加上的前綴grid_,那么生成的分頁字條串就是“/Home/Gridview?grid_paging=2” 10 selectionFieldName 自定義值來替換默認的查詢字符串“行”字段,沒有用過,等解釋 11 sortFieldName 自定義查詢排序QueryString的參數名稱,比如說sortFieldName=”sortField”,那么生成的排序字符串就是“Home/Gridview?grid_sortField=StudentName&grid_sortdir=DESC” 12 sortDirectionFieldName 自定義排序方向QueryString的參數名稱,比如說sortDirectionFieldName=“sortDirectionField”,那么生成的排序串是“Home/Gridview?grid_sortField=StudentName&grid_sortDirectionField=DESC” 屬性解釋
1 DataSource 獲取綁定到的WebGrid的數據源 2 TotalRowCount 獲取綁定到WebGrid的數據總行數 3 PageIndex 獲取WebGrid總頁數 4 SortDirection 獲取或者設置WebGrid的排序方向 5 SelectedIndex 獲取WebGrid的選擇行的index 還有一些比較簡單的屬性,可以自己查一下,如果有不明白的可以聯系我。如果有寫的不好,請你指點,謝謝!
五、總結
通過本例的學習我們對MVC WebGrid有了更深一步的了角,知道了WebGrid Ajax的使用方法,知道了Ajax使用過程中與Search Conditions的綁定,了解了WebGrid中一些主要參數的功能。
留言列表