用户控件,封装一个FlexiGrid的控件,效果图如下:
实现部分:创建一个用户控件View为FlexGridCtl.cshtml,目录结构如下:
FlexGridCtl代码如下:
@model CommonLib.SL.IFlexGridModel @{ var count = 0; } <script src="@Url.Content("~/Content/flexgrid/flexigrid.pack.js")" type="text/javascript"></script> <link href="@Url.Content("~/Content/flexgrid/css/flexigrid/flexigrid.css")" rel="stylesheet" type="text/css" /> <script type="text/javascript"> function test(){} $(function(){ $("#@Model.RenderElement").flexigrid ( { url: '@Model.Action', dataType: 'json', colModel : [ @foreach (var item in Model.FlexGridAttr) { <text> {display:'@(item.Value.DisplayName == null ? item.Key : item.Value.DisplayName)', name:'@item.Key', width:'@(item.Value.Width <= 0 ? "50" : item.Value.Width.ToString())', sortable:@item.Value.Sortable.ToString().ToLower(), align:'@(item.Value.Align == null ? "left" : item.Value.Align)'} @if (count + 1 != Model.FlexGridAttr.Count) { <text>,</text> } </text> count++; } ], buttons : [ {name: '新?增?', bclass: 'add', onpress : test}, {name: '删¦?除y', bclass: 'delete', onpress : test}, {separator: true} ], @{if (0 < Model.FlexGridAttr.Where(p => p.Value.IsSearch == true).Count()) { Write(" searchitems : ["); foreach (var item in Model.FlexGridAttr) { if (item.Value.IsSearch) { <text> {display: '@(item.Value.DisplayName == null ? item.Key : item.Value.DisplayName)', name : '@item.Key'}, </text> } } Write(" ],"); } } sortname: "@Model.FlexGridAttr.Keys.First()", sortorder: "asc", usepager: true, title: '@Model.Title', useRp: true, rp: 15, showTableToggleBtn: true, width: 700, height: 200 } ); }); </script>
注:这里接收实现CommonLib.SL.IFlexGridModel的实现参数,通过循环嵌套动态生成FlexiGrid的代码部分;
该控件页面最终输出一段FlexiGrid的初始js代码并在调用页加载时执行。
这行代码:url: '@Model.Action',指出了加载文档时去异步调用的url,通过该url返回json数据填充FlexiGrid。
再来看下调用页部分:
Index@using Mvc3Test.Models @using CommonLib.SL @model IList<Mvc3Test.Models.Person> @{ View.Title = "主页"; } <h2>@View.Message</h2> @section headinfo{ @Html.Partial("Controls/FlexGridCtl", new FlexGridModel<Person>() { Action = "Home/PersonData", RenderElement = "fgrd", Title = "人员信息表" }) } <table id="fgrd" style="display:none"></table>
上述代码就是View页的代码,只需要调用@Html.Partial(“Controls/FlexGridCtl”,…)这一句则可动态输出FlexiGrid的整个js代码;
其中FlexGridModel<Person>对象则是传递我们定义的参数:
Action:FlexiGrid异步调用的Action的Url ,这个是需要我们在Controller实现的部分
RenderElement:则是FlexiGrid呈现数据的元素Id
Title:FlexiGrid表格的标题
这里我为了方便只定义了这3个参数,当然还可以定义一些其他的参数如:要添加的按钮、回传js函数等等。
后台所用到的cs代码:
类库公用部分,主要是通过反射获取显示列的属性及动态绑定数据:
Indexnamespace CommonLib.SL { public class CustomAttribute:Attribute { } /// <summary> /// 定义FleGrid的特性类,可以根据需要扩充 /// </summary> public class FlexGridAttribute : CustomAttribute { public string DisplayName { get; set; } public int Width { get; set; } public bool Sortable { get; set; } public string Align { get; set; } public bool IsSearch { get; set; } public int No { get; set; } } /// <summary> /// 定义FleGridModel的接口类,定义实现成员,可以根据需要扩充 /// </summary> public interface IFlexGridModel { string Title { get; set; } string RenderElement { get; set; } string Action { get; set; } Dictionary<string, FlexGridAttribute> FlexGridAttr{get;set;} } public class FlexGridModel<T> : IFlexGridModel { public string Title { get; set; } public string RenderElement { get; set; } public string Action { get; set; } private Dictionary<string, FlexGridAttribute> _flexGridAttr; public Dictionary<string, FlexGridAttribute> FlexGridAttr { get { if (_flexGridAttr == null) { _flexGridAttr = AttributeUtil.GetAttributeList(typeof(T)); } return _flexGridAttr; } set { _flexGridAttr = value; } } } public class AttributeUtil { /// <summary> /// 根据Model类型,生成该类型的FlexGridAttribute字典表,根据定义的NO排序 /// </summary> public static Dictionary<string, FlexGridAttribute> GetAttributeList(Type type) { Dictionary<string, FlexGridAttribute> dict = new Dictionary<string, FlexGridAttribute>(); var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var item in props) { var customAttrs = (FlexGridAttribute[])item.GetCustomAttributes(typeof(FlexGridAttribute), false); if (0 < customAttrs.Length) { dict.Add(item.Name, customAttrs[0]); } } var result = dict.OrderBy(p => p.Value.No); Dictionary<string, FlexGridAttribute> dictResult = new Dictionary<string, FlexGridAttribute>(); foreach (var _item in result) { dictResult.Add(_item.Key, _item.Value); } return dictResult; } /// <summary> /// 按照Model显示列的顺序反射生成FlexGrid的行数据 /// </summary> public static List<string> GetFieldData<T>(T data) { var attributes = GetAttributeList(typeof(T)); List<string> list = new List<string>(); foreach (var item in attributes) { var value = typeof(T).GetProperty(item.Key).GetValue(data, null); list.Add(value == null ? string.Empty : value.ToString()); } return list; } } }
Model部分:
Index/// <summary> /// 定义Model类,并在需要显示的字段上加FlexGrid标记 /// </summary> public class Person : Entity { [FlexGrid(DisplayName="用户名",No=0)] public string Login { get; set; } [FlexGrid(DisplayName = "名?",No=1)] public string FirstName { get; set; } [FlexGrid(DisplayName = "姓",No=2)] public string LastName { get; set; } [FlexGrid(DisplayName = "出生日期",No=3)] public DateTime DateOfBirth { get; set; } public Country Country { get; set; } public Country Home { get; set; } public Hobby Hobby { get; set; } public Hobby Habby { get; set; } }
Contrler部分:
Index/// <summary> /// FlexiGrid异步调用的方法,返回JSON数据 /// </summary> public ActionResult PersonData() { JsonFlexiGridData data = new JsonFlexiGridData(); data.rows = new List<FlexiGridRow>(); int count = 0; foreach (var item in Db.Table<Person>()) { data.rows.Add(new FlexiGridRow() { id= count.ToString(), cell =AttributeUtil.GetFieldData<Person>(item) }); count++; } data.total = data.rows.Count; data.page = 1; return Json(data); }