之前寫過用ASP.NET WebForm作為AJAX式資料源的Kendo UI Grid範例,最近計劃在一個小專案試用ASP.NET MVC 4 RC,面對的第一個需求又是"以清單呈現查詢結果",就來看看如何用ASP.NET MVC 4 RC滿足Kendo UI Grid的需求吧!
記得前一次用ashx寫資料端,花了不少功夫處理分頁及排序,而且還沒實做Filter過濾功能。但在ASP.NET MVC上,要整合Kendo UI Grid,則有很酷的方便選擇 -- KendoGridBinder!!
以下是我實做Kendo UI Grid + ASP.NET MVC 4的過程:
- 建立一個ASP.NET MVC 4專案
- 使用NuGet安裝KendoUIWeb及KendoGridBinder
- 借用上回的SimMemberInfo Model類別 ,放在Model目錄下: 排版顯示純文字
using System;using System.Collections.Generic;using System.Drawing;using System.Linq;using System.Reflection;using System.Web;namespace KendoGridMvc.Models{//模擬資料物件public class SimMemberInfo
{public string UserNo; //會員編號
public string UserName; //會員名稱
public DateTime RegDate; //註冊日期
public int Points; //累積點數
//模疑資料來源public static List<SimMemberInfo> SimuDataStore = null;
static SimMemberInfo(){Random rnd = new Random();//借用具名顏色名稱來產生隨機資料string[] colorNames = typeof(Color)
.GetProperties(BindingFlags.Static | BindingFlags.Public)
.Select(o => o.Name).ToArray();
SimuDataStore =
colorNames
.Select(cn => new SimMemberInfo(){UserNo = string.Format("C{0:00000}", rnd.Next(99999)),
UserName = cn,
RegDate = DateTime.Today.AddDays(-rnd.Next(1000)),
Points = rnd.Next(9999)
}).ToList();
}
}
}
- 要引用Kendo UI,需要載入必要的JS及CSS,此時昨天介紹過的ASP.NET MVC打包壓縮功能馬上派上用場! 編輯App_Start/BundleConfig.cs,加入以下程式: 排版顯示純文字
bundles.Add(new ScriptBundle("~/bundles/kendoUI").Include(
"~/Scripts/kendo/2012.1.322/kendo.web.min.js"));
//經實測,SytleBundle virtualPath參數使用"2012.1.322"會有問題,故向上搬移一層//將/Content/kendo/2012.1.322的內容搬至Content/kendo下bundles.Add(new StyleBundle("~/Content/kendo/css").Include(
"~/Content/kendo/kendo.common.min.css","~/Content/kendo/kendo.blueopal.min.css"));
PS: 此處有一個眉角:由於CSS檔路徑會被當成引用圖檔的基準,原本Kendo UI的.css及圖檔被放在~/Content/kendo/2012.1.322/下,理論上StyleBundle應設成"~/Content/kendo/2012.1.322/css”,才能引導瀏覽器到該目錄下取用圖檔。不幸地,我發現StyleBundle的virtualPath參數出現2012.1.322時,會導致Styles.Render("~/Content/kendo/2012.1.322/css”)時傳回HTTP 404錯誤~ 為克服問題,我決定將2012.1.322目錄的內容向上搬一層,直接放在~/Content/keno目錄下,並將virtualPath設成"~/Content/kendo/css",這樣就能避開問題。 - 為了省去每個View都要加掛Kendo UI JS及CSS的麻煩,我索性將它們加在~/Views/Shared/_Layout.cshtml中: 排版顯示純文字
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/themes/base/css", "~/Content/css","~/Content/kendo/css")
@Scripts.Render("~/bundles/modernizr")@Scripts.Render("~/bundles/jquery", "~/bundles/kendoUI")@RenderSection("scripts", required: false)</head>
<body>
@RenderBody()
</body>
</html>
- 網頁Index.cshtml的Client端做法,則跟上回WebForm AJAX範例幾乎完全相同:排版顯示純文字
@section Scripts
{<style>
body { font-size: 9pt; }#dvGrid { width: 500px; }span.hi-lite { color: red; }#dvGrid th.k-header { text-align: center; }</style>
<script>
$(function () {//建立資料來源物件var dataSrc = new kendo.data.DataSource({
transport: {read: {//以下其實就是$.ajax的參數type: "POST",url: "/Home/Grid",dataType: "json",data: {//額外傳至後方的參數keywd: function () {return $("#tKeyword").val();
}
}
}
},
schema: {//取出資料陣列data: function (d) { return d.data; },
//取出資料總筆數(計算頁數用)total: function (d) { return d.total; }
},
pageSize: 10,
serverPaging: true,serverSorting: true});
//JSON日期轉換var dateRegExp = /^\/Date\((.*?)\)\/$/;window.toDate = function (value) {var date = dateRegExp.exec(value);return new Date(parseInt(date[1]));
}
$("#dvGrid").kendoGrid({dataSource: dataSrc,
columns: [
{ field: "UserNo", title: "會員編號" },{ field: "UserName", title: "會員名稱",template: '#= "<span class=\\"u-name\\">" + UserName + "</span>" #'},
{ field: "RegDate", title: "加入日期",template: '#= kendo.toString(toDate(RegDate), "yyyy/MM/dd")#'},
{ field: "Points", title: "累積點數" },],
sortable: true,pageable: true,dataBound: function () {//AJAX資料Bind完成後觸發var kw = $("#tKeyword").val();
//若有設關鍵字,做Highlight處理if (kw.length > 0) {var re = new RegExp(kw, "g");
$(".u-name").each(function () {
var $td = $(this);
$td.html($td.text()
.replace(re, "<span class='hi-lite'>$&</span>"));});
}
}
});
//按下查詢鈕$("#bQuery").click(function () {
//要求資料來源重新讀取(並指定切至第一頁)dataSrc.read({ page: 1, skip: 0 });//Grid重新顯示資料$("#dvGrid").data("kendoGrid").refresh();
});
});
</script>
}
<div style="padding: 10px;">
關鍵字:
<input id="tKeyword" /><input type="button" value="查詢" id="bQuery" />
</div>
<div id="dvGrid">
</div>
- 最後來到重頭戲,負責以AJAX方式傳回資料的HomeController.cs的Grid() Action:什麼? 沒看錯吧? 這樣就好?排版顯示純文字
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using KendoGridBinder;using KendoGridMvc.Models;namespace KendoGridMvc.Controllers{public class HomeController : Controller
{//// GET: /Home/public ActionResult Index(){return View();}
public JsonResult Grid(KendoGridRequest request, string keywd)
{var result = SimMemberInfo.SimuDataStore.Where(o =>
string.IsNullOrEmpty(keywd) || o.UserName.Contains(keywd));return Json(new KendoGrid<SimMemberInfo>(request, result));
}
}
}
是的,感謝Ryan Whitmire及Jose Ball的佛心與巧思,只要return Json(new KendoGrid<T>(KendoGridRequest, IEnumerable<T>)),餘下的換頁、排序,甚至欄位過濾功能,就都交給KendoGridBinder全權處理囉!
實際測試,換頁、排序功能一切正常,有了Kendo UI助陣,ASP.NET MVC之路順利多了~
No comments:
Post a Comment