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

二、本文内容

  1. WebGrid的使用
  2. WebGrid Sorting(排序) Ajax的实现
  3. WebGrid Search Conditions(查询条件)的绑定
  4. 总结
  5. 代码下载 (下载

三、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的使用,得到结果如下:

[原创] MVC3 Web.Helpers – WebGrid Ajax 及查询绑定_第1张图片

2. WebGrid Sorting(排序) Ajax的实现

我们看,在上面的View代码中黄色背景表示的是创建WebGrid对象实例,其中有这样一行ajaxUpdateContainerId:"DivGrid",他表示的是当WebGrid发生AjaxUpdate事件后,将更新后内容显示到指定的元素中。在我们示例中,我们指定的是一个Div对象。也就是说我们期望得到的结果是,当我们点击标题行的列进行排序后,应该把排序后的新内容放到这个Div中,并且是Ajax操作。但是在实际操作中,浏览器会提示如下信息:

[原创] MVC3 Web.Helpers – WebGrid Ajax 及查询绑定_第2张图片

为什么他会提示这样的信息呢?我们点击上面的结果,查看源代码,有如下行:

[原创] MVC3 Web.Helpers – WebGrid Ajax 及查询绑定_第3张图片

我们可以看到,他生成的是一个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.,如下图所示:

[原创] MVC3 Web.Helpers – WebGrid Ajax 及查询绑定_第4张图片

那么当我们点击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里就把分页的数据直接返回,那么将大大减少数据传输量(数据库分页也会比较快)。

Update(20 Dec 2010):

如果我们将查询条件作为Routing输入,那么我在Paging或者Sorting的时候它会保持查询条件的存在。

四、方法及参数说明

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中一些主要参数的功能。

你可能感兴趣的:(Ajax)