Kendo UI DropDownListFor html 包装器 - 如何将 BindTo 设置为模型中的集合?而不是 ViewData 或 Viewbag

Kendo UI DropDownListFor html wrapper - How to set up the BindTo to a collection in model? Rather than ViewData or Viewbag

我正在了解 Kendo UI。我们正朝着对 MVC 应用程序视图中的所有内容使用 Kendo UI 的方向发展。

我正在尝试绑定到 Kendo 网格每一行中模型对象内的集合。我们正在使用 EditorTemplate 来实现下拉菜单,这已经用于几个更简单的示例。

然而,在这种情况下,我们试图通过该对象中 属性 的值过滤此下拉菜单的来源。

模型对象:

public class AppRolesForUserVM
{
    public int AppId { get; set; }
    public string appName { get; set; }
    public AppRole appRole { get; set; }
    public AppUser appUser { get; set; }
    public List<AppRole> appRolesList { get; set; }

}

来自网格的片段:

 @(Html.Kendo().Grid<AppRolesForUserVM>()
              .Name("ApplicationGrid")
              .Columns(columns =>
              {
                  columns.Bound(p => p.AppId).Title("Application Id").Width(50);
                  columns.Bound(p => p.appName).Title("Application Name").Width(100);                    
                  columns.Bound(p => p.appRole.Id).ClientTemplate("#=appRole.Name#").EditorTemplateName("AppRolesForUser").Title("AppRole").Width(100);  // ***** 

上面代码的最后一列是我们一直试图实现这个下拉菜单的地方。它指的是下面的 editorTemplateName AppRolesForUser:

AppRolesForUser EditorTemplate:

@model AdminAuthorization.Models.ViewModels.AppRolesForUserVM

@(Html.Kendo().DropDownListFor(p => p.appRole.Id)
    .Name("appRole.Id")
    .DataTextField("Name")
    .DataValueField("Id")
    .BindTo((IEnumerable)ViewData["ListOfRoles"]) // ***** 
)

我标记 **** 的地方是我希望弄清楚如何根据模型对象 AppRolesForUserVM 的输入参数实际提取数据...传递 appId 属性 获取该应用程序的角色列表...很简单吧?

按照我现在的设置方式,下拉列表显示在您 select 编辑按钮之后,但是下拉列表是空的! Link 到没有任何内容的下拉菜单图像:http://i.stack.imgur.com/bEcMw.png

我一直在尝试更改编辑器模板中的 BindTo 以引用 Model.appRolesList,但每次我都遇到空指针异常,因为我猜模型没有被传递给这个 dropdownlistFor helper?不确定...

我的团队一直对如何实现此功能感到困惑。我们都是 Kendo 的新手,因此在涉及这些类型情况的来龙去脉时,小组中没有专家。

提前感谢您抽出宝贵时间阅读本文! :)

编辑:外键方法似乎是实现此功能的最佳方式,但我 运行 遇到了尝试从外键 html 包装器引用集合的问题.当我回到办公桌前时,我会 post 另一个代码片段

使用代码片段编辑 2:

这是更新后的网格,仅使用 .ForeignKey 引用而不是 .Bound。在这个例子中,我仍然在努力引用 AppRolesForUserVM 对象中的对象列表......可能有人有这样做的语法吗?我在 Kendo 演示中看到的大多数示例都非常简单,它们引用存储在 ViewData 或 ViewBag 中的集合。

 @(Html.Kendo().Grid<AppRolesForUserVM>()
                  .Name("ApplicationGrid")
                  .Columns(columns =>
                  {
                      columns.Bound(p => p.AppId).Title("Application Id").Width(50);
                      columns.Bound(p => p.appName).Title("Application Name").Width(100);
                      columns.ForeignKey(p => p.appRole.Id, q.appRolesList).ClientTemplate("#=appRole.Name#").Title("App Role").Width(100);

我还没有使用 EditorTemplate 完成此操作,但另一种选择是制作一个控制器操作 returns 角色并使用它:

public JsonResult ReadRoles(int id)
{
    var roleList = context.Roles.Where(r => r.AppId == id).OrderBy(r => r.Name).ToSelectList(r => r.Id.ToString(), r => r.Name);
    var result = Json(roleList, JsonRequestBehavior.AllowGet);
    return result;
}

然后你的下拉菜单变成这样:

@(Html.Kendo().DropDownListFor(p => p.appRole.Id)
    .Name("appRole.Id")
    .DataSource(source => source.Read(read => read.Action("ReadRoles", "App", new { id = @Model.AppId })
    .DataTextField("Name")
    .DataValueField("Id")
    .HtmlAttributes(new {data_value_primitive = "true"})
)

其中 App 是您将读取操作放入其中的控制器,ToSelectList 是我们编写的用于创建 IEnumerable 的扩展方法。

使用我能够使用的最终方法进行编辑: 我已经开始工作并且它正在使用与此答案中的方法类似,只是稍作调整。

我现在使用的下拉编辑器模板代码是:

@model Project.Models.ViewModels.AppRolesForUserVM

@(Html.Kendo().DropDownListFor(p => p.appRole.Id)
    .Name("appRole.Id")
    .DataSource(source => source.Read(read => read.Action("ReadRoles", "App").Data("onRead")))
    .DataTextField("Name")
    .DataValueField("Id")
    .HtmlAttributes(new { data_value_primitive = "true" })
)

数据源声明中的.Data("onRead")调用了下面的函数,获取正在编辑的数据行,然后从该行的第一列中获取值;其中包含我要传递给控制器​​读取操作的 ID:

    <script type="text/javascript">
        function onRead(e) {
            var row = $(event.currentTarget).find(".k-grid-edit-row");
            var id = row.find("td:first").html();
            return { id: id };
        }
    </script>