创建一个复选框矩阵,支持在ASP.NET MVC中回发

时间:2016-06-09 15:14:58

标签: asp.net-mvc asp.net-mvc-5

我正在尝试通过MVC 5中的视图模型来管理选择值矩阵的方法。

我有公司列表和角色列表。每个公司的角色都是一样的。我想要的是输出公司/角色矩阵,每个组合都有一个复选框。这允许用户选择该人员对每个公司的角色。

我可以使用嵌套的foreach循环渲染输出,但我不禁认为使用MVC和编辑模板有更好的方法来实现这一点。

以下是布局的粗略示例。因此,每个公司都作为一列输出,每个角色都作为一行输出。然后将每个公司的复选框输出到每一行。

Company/Role  COMPANY1 COMPANY2 COMPANY3
ROLE1            [X]       []      []
ROLE2            []        []      [X]   
ROLE3            []        []      []

增加的复杂性是能够处理回发。我的视图模型结构目前是..

public class RequestViewModel
    {
        public Guid Id { get; set; }
        public List<CompanyAccessViewModel> CompanyAccessViewModels { get; set; }
    }

public class CompanyAccessViewModel
    {
        public int Company { get; set; }
        public Guid Id { get; set; }
        public Guid RequestId { get; set; }
        public List<Company> ListCompanies { get; set; }
        public List<Role> ListRoles { get; set; }
        public List<CompanyAccessRoleViewModel> CompanyAccessRoleViewModels { get; set; }
    }

public class CompanyAccessRoleViewModel
    {
        public Guid AccessRequirementId { get; set; }
        public Guid Id { get; set; }
        public string Role { get; set; }
    }

ListCompanies是所有公司的列表。 ListRoles是所有角色的列表。

1 个答案:

答案 0 :(得分:1)

与往常一样,从视图模型开始,以表示您想要显示/编辑的内容。

public class RoleVM
{
    public int ID { get; set; }
    public string Name { get; set; }
    public List<CompanyVM> Companies { get; set; }
}
public class CompanyVM
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

和GET方法

[HttpGet]
public ActionResult Index()
{
    IEnumerable<Role> roles = db.Roles;
    IEnumerable<Company> companies = db.Companies;
    List<RoleVM> model = roles.Select(x => new RoleVM()
    {
        ID = x.ID,
        Name = x.Name,
        Companies = companies.Select(y => new CompanyVM()
        {
            ID = y.ID,
            Name = y.Name
        }).ToList()
    }).ToList();
    // For editing existing roles, set the IsSelected property
    // of the respective CompanyVM to true
    return View(model);
}

和视图

@model List<RoleVM>
@using (Html.BeginForm())
{
    <table>
        <thead>
            <tr>
                <th>Company/Role</th>
                @foreach(var company in Model.FirstOrDefault().Companies)
                {
                    <th>@company.Name</th>
                }
            </tr>
        </thead>
        <tbody>
            @for (int i = 0; i < Model.Count; i++)
            {
                <tr>
                    <td>
                        @Model[i].Name
                        @Html.HiddenFor(m => m[i].ID)
                        @Html.HiddenFor(m => m[i].Name)
                    </td>
                    @for (int j = 0; j < Model[i].Companies.Count; j++)
                    {
                        <td>
                            @Html.HiddenFor(m => m[i].Companies[j].ID)
                            @Html.HiddenFor(m => m[i].Companies[j].Name)
                            @Html.CheckBoxFor(m => m[i].Companies[j].IsSelected)
                        </td>
                    }
                </tr>
            }
        </tbody>
    </table>    
    <button type="submit">Save</button>
}

将发布到

[HttpPost]
public ActionResult Index(List<RoleVM> model)
{
    // To get the companies for each role
    foreach (var role in model)
    {
        var selectedCompanies = role.Companies.Where(x => x.IsSelected);

请注意,在提交表单时,使用嵌套的foreach循环永远不会正确绑定(您需要使用for循环)。如果您想使用EditorTemplates(您的属性可以是IEnumerable<T>而不是IList<T>,那么在/Views/Shared/EditorTemplates/RoleVM.cshtml

中创建一个部分
@model RoleVM
<tr>
    <td>
        @Model.Name
        @Html.HiddenFor(m => m.ID)
        @Html.HiddenFor(m => m.Name)
    </td>
    @Html.EditorFor(m => m.Companies)
</tr>

和另一个/Views/Shared/EditorTemplates/CompanyVM.cshtml

@model CompanyVM
<td>
     @Html.HiddenFor(m => m.ID)
     @Html.HiddenFor(m => m.Name)
     @Html.CheckBoxFor(m => m.IsSelected)
</td>

,主视图将是

@model List<RoleVM>
.... // as above
<tbody>
    @Html.EditorFor(m => m)
</tbody>