我有以下两难困境:
我正在尝试在部分视图中创建一个Kendo UI Grid,它将与不同类型的对象一起使用,并且可以支持删除或创建等操作。
该对象如下所示:
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&lt;员工&gt;。
但这是不正确的,因为我想使用Grid&lt;'任何类型的对象'&gt;,但语法不会让我给它一个字符串,然后将其更改为类类型。 我尝试过这样的事情:
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))
)
)
的更新: 的
我找到了解决方案。
@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&lt; '对象类型'&gt;。
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是一个对象列表(空洞和孤独 - 只是为了欺骗那些不起作用的函数)。
FINAL结果是我有一个通用网格接受任何带有删除和编辑按钮的对象数组,这些按钮指向可以根据自己的偏好自定义的功能 - 它可以打开包含部分数据的弹出窗口查看,完整视图或任何您想要的。我甚至定制了一个删除功能来删除Ajax帖子,而不需要用户进行任何确认,它完全有效。