1

情况

我有一个用户列表,其中有一个角色列表,我希望在剑道多选中看到可编辑的角色列表。

问题

使用我拥有的代码,它变得非常奇怪,在顶部它显示了一堆文本框(在我看来),而在多选框应该是我看到的所有地方都是向上和向下箭头。

到目前为止我的代码:

foreach (var u in Model.Users)
{
<div class="form-group">
    <div class="col-sm-2">
        @Html.Label(u.Name)
    </div>
    <div>
        @Html.Kendo().MultiSelectFor(m => u.Roles).BindTo(Model.UserRoles);
    </div>
</div>
}

视图模型

public class CompanyViewModel
{
    public IEnumerable<UserDto> Users { get; set; }
    public IEnumerable<UserRoleDto> UserRoles { get; set; }
}

用户Dto

public class UserDto
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string Name
    {
        get
        {
            return string.Format("{0} {1} {2}", FirstName, MiddleName, LastName);
        }
    }

    public IEnumerable<SelectListItem> Roles { get; set; }
}

这是我这样渲染页面时页面的片段

div class="k-widget k-multiselect k-header" unselectable="on" title style>

div class="k-multiselect-wrap k-floatrap" unselectable="on">...</div>

div class="k-widget k-multiselect k-header" unselectable="on" title style>

div class="k-multiselect-wrap k-floatrap" unselectable="on">...</div>

div class="k-widget k-multiselect k-header" unselectable="on" title style>

div class="k-multiselect-wrap k-floatrap" unselectable="on">...</div>

div class="k-widget k-multiselect k-header" unselectable="on" title style>

div class="k-multiselect-wrap k-floatrap" unselectable="on">...</div>

这会不断重复自己多次。

我怀疑我如何根据用户而不是模型中的某些内容来制作多选存在问题,但我对剑道的了解太低,无法理解应该如何完成。

任何帮助将非常感激

4

1 回答 1

2

您的代码有多个问题。

首先,KendoMultiSelectFor()创建了一个 html<select multiple>标签(虽然它使用隐藏它display: none;并添加了自己的 html,但它<select>是用于绑定和回发到控制器的)。A<select multiple>只能绑定到并且只能回发简单值类型的数组,而不是复杂对象,因此您不能绑定到 typeof 的属性IEnumerable<IEnumerable<SelectListItem>。您的Roles属性需要IEnumerable<int> Roles { get; set; }假设您想要回发选定的角色 ID。

接下来,您UserRoles需要IEnumerable<SelectListItem>SelectList哪些是.BindTo()助手的方法所必需的。

最后,您不能使用foreach循环绑定到集合属性。它将生成name与您的模型无关的重复属性,因此不会绑定(并且还会生成id无效 html 的重复属性)。您需要为EditorTemplate集合中的类型使用自定义(通常for循环是合适的,但由于在循环中使用帮助程序的问题,它不适用于您的情况)

您的视图模型需要

public class CompanyViewModel
{
  public IEnumerable<UserViewModel> Users { get; set; }
  public IEnumerable<SelectListItem> RoleList { get; set; }
}
public class UserViewModel
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  ....
  [Display(Name = "Roles")]
  public IEnumerable<int> SelectedRoles { get; set; }
}

然后创建一个局部视图/Views/Shared/EditorTemplates/UserViewModel.cshtml

@model yourAssembly.UserViewModel
@Html.HiddenFor(m => m.Id)
....
@Html.LabelFor(m => m.SelectedRoles)
@Html.Kendo().MultiSelectFor(m => u.SelectedRoles)
  .BindTo((IEnumerable<SelectListItem>)ViewData["roleList"])
....

在主视图中

@model yourAssembly.CompanyViewModel
@using (Html.BeginForm())
{
  @Html.EditorFor(m => m.Users, new { roleList = Model.RoleList })
  <input type="submit" .../>
}

这里发生的是该EditorFor()方法将UserViewModel根据模板中的 html 为集合中的每个生成 html。此外,它将 传递SelectList给模板作为附加ViewData

旁注:我建议您从使用标准 MVC 列表框助手开始

@Html.ListBoxFor(m => u.SelectedRoles, (IEnumerable<SelectListItem>)ViewData["roleList"])

在模板中以确保其一切正常,然后更改为@Html.Kendo().MultiSelectFor()

于 2015-08-15T08:35:45.893 回答