我有以下两难困境:
我试图在部分视图中创建一个Kendo UI Grid,它将与不同类型的对象一起使用,并且可以支持诸如Delete或Create之类的操作 .
该对象如下所示:
public class GridViewModel
{
public Type ObjectType { get; set; }
public IEnumerable<object> Items { get; set; }
public GridViewModel(Type type, IEnumerable<object> items)
{
Items = items;
ObjectType = type;
}
}
ObjectType是Type类型的变量,它保留类的类型 . 例如员工,产品,发票或任何东西 .
Items是前面提到的类型的IEnumerable对象列表 .
假设我们有一个员工视图,我们在内部调用以下内容:
@model IEnumerable<Employee>
@{
GridViewModel gridModel = new GridViewModel(typeof(Employee), Model);
}
@{
Html.RenderPartial("_AdvancedGrid", gridModel);
}
这样我们就可以将指定对象的部分视图作为模型加载 .
现在局部视图中的Kendo UI Grid:
@model XMLProject.Models.GridViewModel
@{
System.Reflection.PropertyInfo[] propertyArray = Model.ObjectType.GetProperties();
}
@(Html.Kendo().Grid<Employee>()
.Name("Grid")
.Columns(columns =>
{
foreach (var property in propertyArray)
{
columns.Bound(property.Name);
}
columns.Command(c => c.Destroy());
})
.ToolBar(toolbar => toolbar.Create())
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id("Id"))
.Destroy(update => update.Action("Delete", "Products"))
.Read(read => read.Action(ViewBag.PageLayout.ReadDataActionName, ViewBag.PageLayout.ControllerName))
.Update(update => update.Action("Products_Update", "Home"))
.Create(create => create.Action("Products_Create", "Home"))
)
)
如您所见,我正在使用Grid <Employee> .
但这是不正确的,因为我想使用Grid <'任何类型的对象'>,但语法不会让我给它一个字符串,然后将其更改为类类型 . 我尝试过这样的事情:
Html.Kendo().Grid<(Type)Model.ObjectType>
Html.Kendo().Grid<typeof(Model.ObjectType)>
......和其他愚蠢的方式 .
我的最后一个问题是,我是否能以某种方式欺骗编译器从项目中看到一个字符串或类似的东西 .
我也试过类似的东西:
Html.Kendo().Grid<IProduct>
这种方法有效,但这意味着我想在网格中使用的任何对象必须具有Product接口的所有字段 .
作为最后的观察,我做了这项工作,但没有通过使用不同的语法实现网格中内置的任何删除/创建/更新操作:
@(Html.Kendo().Grid(Model.Items)
.Name("Grid")
.Columns(columns =>
{
foreach (var property in propertyArray)
{
columns.Bound(property.Name);
}
})
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action(ViewBag.PageLayout.ReadDataActionName, ViewBag.PageLayout.ControllerName))
)
)
UPDATE:
我找到了解决方案 .
@model GridViewModel
@using Kendo.Mvc.UI;
@{
System.Reflection.PropertyInfo[] propertyArray = Model.ObjectType.GetProperties();
List<object> mockList = new List<object>();
}
@(Html.Kendo().Grid(mockList)
.Name("Grid")
.Columns(columns =>
{
foreach (var property in propertyArray)
{
columns.Bound(property.Name);
}
columns.Command(c => c.Custom("Delete").Click("kendoGrid.onDeleteButtonClicked"));
columns.Command(c => c.Custom("Edit").Click("kendoGrid.onEditButtonClicked"));
})
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action(Model.ReadDataActionName, ViewBag.PageLayout.ControllerName))
)
)
我所做的是摆脱所有无用的标准函数,如Kendo提供的Destroy或Create,因为它们需要使用Grid <'object type'>的synthax .
GridViewModel对象现在看起来像这样:
public class GridViewModel
{
public Type ObjectType { get; set; }
public string ReadDataActionName { get; set; }
public GridViewModel(Type type, string actionName)
{
ObjectType = type;
ReadDataActionName = actionName;
}
}
其中ReadDataActionName是负责返回Kendo网格可以读取的Json对象列表的操作名称 .
然后我创建了自定义命令,指向在Jquery中创建的自定义函数,它们作为参数发送一个非常复杂的对象,该对象具有(除了所有其他东西)我点击的网格中的Json对象 .
最后一件事是数据源中的.Read函数 . 这必须指向一个返回特殊类型Json的函数(请参阅Kendo文档,了解您的操作必须在其演示示例中返回的Json类型) .
那么你就不需要像你看到的那样一个对象数组:
@(Html.Kendo().Grid(mockList)
...
)
mocklist是一个对象列表(空洞和孤独 - 只是为了欺骗那些不起作用的函数) .
最后的结果是我有一个通用网格接受任何带有删除和编辑按钮的对象数组,这些按钮指向可以根据自己的偏好自定义的功能 - 它可以打开包含部分视图数据的弹出窗口,全景或任何你想要的东西 . 我甚至定制了一个删除功能来删除Ajax帖子而不需要用户进行任何确认,它完全有效 .