您的位置:知识库 »

[原创] MVC3 Web.Helpers – WebGrid Ajax 及查询绑定

作者: 我-大熊  来源: 博客园  发布时间: 2010-10-28 15:33  阅读: 4997 次  推荐: 1   原文链接   [收藏]  

本文只代表作者在一定阶段的认识与理解。

  一、写作前提

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

image

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

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

image

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

image

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

image

那么当我们点击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中一些主要参数的功能。

1
3
标签:MVC

热门文章

    最新文章

      最新新闻

        热门新闻