之前寫過用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