我是否应该使用 ViewBag 将列表传递给视图

本文关键字:列表 视图 ViewBag 是否 | 更新日期: 2023-09-27 18:36:58

不知道为什么我被投票了,但我将在做一些研究和测试后重写我的问题。这是我用来学习MVC/EF/Repository/Bootstrap等的副项目。我每周只有几个晚上在这里工作几个小时。

基本原始问题:

我知道我真的应该在 ViewModel 中使用 List<> 将数据传递给视图,但我不确定它如何或是否满足我的要求。

我正在尝试做的是获取要在表格中显示的用户列表,该表格每行都有一个复选框。在该表上方,我希望有一个可以分配给它们的组列表。从下拉列表 (DDL) 中选择该部分,然后选中要将其分配给谁。这是我想要分配为列表并传递给视图的组/部分。

因此,我

有一个带有列表的 ViewModel,并且我正在使用存储库来填充 VM。我不知道该怎么做的是在哪里/何时用每个虚拟机对象填充该列表,即使我这样做并且有 50 个用户,我也不想去数据库 50 次来提取相同的信息。这就是为什么我认为在这种情况下使用 ViewBag 将该组列表传递给视图可能是合理的。另一方面,我想学习如何在 VM 中正确填充该列表以供将来编码。

更新的问题/代码:

因此,经过更多研究并遵循一些建议,我现在得到了以下代码。我仍然不确定如何在我的视图模型中正确填充我的巡逻,以便在我的视图中填充 DDL。

目前,我的视图显示带有复选框的表格。现在,我又开始着手获取填充 DDL 的值,然后我必须处理发布到控制器、循环查找检查行并更新数据库的工作。就我而言,每个成员记录默认为 PatrolId=0,此页面应允许我将 PatrolId 更新为 DDL 中的值。

PatrolMemberViewModel 中的 Patrols 属性应该是大约 5 条记录的列表,我将从数据库表中提取这些记录,而不是在 DDL 中进行硬编码。

视图模型:

 public class PatrolViewModel
    {
        public int PatrolId { get; set; }
        public string PatrolName { get; set; }
    }
    public class PatrolMemberViewModel
    {
        [Key]
        public int MemberId { get; set; }
        public int PatrolId { get; set; }

        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Display(Name = "Phone")]
        public string PhonePrimary { get; set; }

        [Display(Name = "Email")]
        public string EmailPrimary { get; set; }
        public bool IsSelected { get; set; }
        public PatrolViewModel Patrols { get; set; }
    }

控制器:

public ViewResult Unassigned()
        {
            try
            {
                IEnumerable<PatrolMemberViewModel> model = repository.SelectAllUnassigned();
                return View(model);
            }
            catch (Exception)
            {
                ModelState.AddModelError(string.Empty, "Error retrieving the record.");
                return View();
            }
        }

存储 库:

public IEnumerable<PatrolMemberViewModel> SelectAllUnassigned()
        {
            using (DataContext db = new DataContext())
            {
                var results = (from p in db.Person
                               where p.IsActive == true
                               && p.IsScout == true
                               && p.PatrolId == 0
                               select new PatrolMemberViewModel
                               {
                                   MemberId = p.PID,
                                   FirstName = p.FirstName ?? string.Empty,
                                   LastName = p.LastName ?? string.Empty,
                                   EmailPrimary = p.EmailPrimary ?? string.Empty,
                                   PhonePrimary = p.PhonePrimary ?? string.Empty,
                                   PatrolId = p.PatrolId,
                                   IsSelected = false
                               }
                                ).OrderBy(o => o.LastName).ThenBy(o => o.FirstName).ToList();
                return results;
            }
        }

视图:

@model IList<ProjectName.ViewModels.PatrolMemberViewModel>
@{
    ViewBag.Title = "Unassigned";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Patrols</h2>

@using (Html.BeginForm("Update", "Patrol", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(false, "", new { @class = "alert alert-danger" })
    <table class="table table-bordered table-striped table-hover table-condensed tbackground">
        <tr>
            <th class="text-center">
            </th>
            <th class="text-center">
                First Name
            </th>
            <th class="text-center">
                Last Name
            </th>
            <th class="text-center">
                Email
            </th>
            <th class="text-center">
                Phone
            </th>
        </tr>

        @for (var i = 0; i < Model.Count(); i++)
        {
        <tr>
            <td class="text-center">
                @Html.CheckBoxFor(m => m[i].IsSelected)
            </td>
            <td>
                @Html.DisplayFor(m => m[i].FirstName)
            </td>
            <td>
                @Html.DisplayFor(m => m[i].LastName)
            </td>
            <td>
                <a href="mailto:@Model[i].EmailPrimary">@Model[i].EmailPrimary</a>
            </td>
            <td class="text-center">
                @Html.DisplayFor(m => m[i].PhonePrimary)
            </td>
        </tr>
        }
    </table>
    <div class="control-wrapper">
        <input type="submit" id="btnSubmit" value="Assign" class="btn btn-success" />
    </div>
}
<p>&nbsp;</p>

我是否应该使用 ViewBag 将列表传递给视图

首先创建视图模型来表示要在视图中显示/编辑的内容。可以使用PatrolMemberViewModel,但要删除[Key]属性以及int PatrolIdPatrolViewModel Patrols属性。

然后创建父视图模型

public class AssignPatrolViewModel
{
    [Display(Name = "Patrol")]
    [Required(ErrorMessage = "Please select a patrol")]
    public int? SelectedPatrol { get; set; }
    public IEnumerable<SelectListItem> PatrolList { get; set; }
    public List<PatrolMemberViewModel> Members { get; set; }
}

而你的 GET 方法将是

public ViewResult Unassigned()
{
  var model = new AssignPatrolViewModel
  {
      PatrolList = new SelectList(db.Patrols, "PatrolId", "PatrolName"), // modify to suit
      Members = repository.SelectAllUnassigned().ToList()
  };
  return View(model);
}

并在视图中

@model AssignPatrolViewModel
....
@using (Html.BeginForm())
{
    @Html.LabelFor(m => m.SelectedPatrol)
    @Html.DropDownListFor(m => m.SelectedPatrol, Model.PatrolList, "Please select")
    @Html.ValidationMessageFor(m => m.SelectedPatrol)
    <table>
        .... // thead elements
        <tbody>
            @for(int i = 0; i < Model.Members.Count; i++)
            {
                <tr>
                    <td>
                        @Html.CheckBoxFor(m => m.Members[i].IsSelected)
                        @Html.HiddenFor(m => m.Members[i].MemberId)
                        // add other hidden inputs for properties you want to post
                    </td>
                    <td>@Html.DisplayFor(m => m.Members[i].FirstName)</td>
                    ....
                </tr>
            }
        </tbody>
    </table>
    <input type="submit" value="Assign" class="btn btn-success" />
}

然后在 POST 方法中

[HttpPost]
public ViewResult Unassigned(AssignPatrolViewModel model)
{
    if (!ModelState.IsValid)
    {
        model.PatrolList = new SelectList(db.Patrols, "PatrolId", "PatrolName");
        return View(model);
    }
    // Get selected ID's
    IEnumerable<int> selected = model.Members.Where(m => m.IsSelected).Select(m => m.MemberId);
    // Get matching data models
    var members = db.Person.Where(p => selected.Contains(p.PID)); // modify to suit
    // loop each each member, update its PatrolId to the value of model.SelectedPatrol
    // save and redirect
}

您可以为视图模型创建一个新类,其中的用户列表和部分列表作为属性。有些人似乎喜欢这种方法。

但我认为您使用 ViewBag 来传递部分列表是完全有效的。对于这样的 DDL,我一直这样做。