我是否应该使用 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> </p>
首先创建视图模型来表示要在视图中显示/编辑的内容。可以使用PatrolMemberViewModel
,但要删除[Key]
属性以及int PatrolId
和PatrolViewModel 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,我一直这样做。