我正在一个MVC项目中,尝试在提交给数据库之前查看控制器已处理的复杂对象列表。对这个问题至关重要的是两个组成部分。
首先,该视图显示每个对象并带有一个复选框,以“保留此对象”(即:该对象适合添加)
第二,复杂对象全部来自一个源-但是每个复杂对象列表可以有多个源。我还需要为每个来源选择一个复选框,每个来源仅显示一次,表示不同的标志(不保留,但如果来源是完整的或仅是部分的)
因为这是关于过程生成的地图,所以有两件事:
Map Tiles列表(复杂对象的列表)-如果我们保留要添加到数据库或忽略它的每个复选框,则都带有一个复选框。 地图标识符(源)-每个运行带有一个复选框,指示我们是否知道这些是该运行的所有图块,还是仅少数几个图块。
到目前为止,我如何解决此问题:
在我看来,当我不担心区分来源时,我使用了EditorForModel。这对于使复选框重新显示在帖子中非常有用
<form asp-controller="Process" asp-action="Keep" method="post">
<input type="submit" value="Submit Data" id="btnSubmit" />
<hr />
@Html.EditorForModel()
<input type="submit" value="Submit Data" id="btnSubmit" />
<hr />
</form>
带有原始模型的模板,该模板只是地图的每个图块。这并没有区分地图-我只是将所有图块(无论它们来自什么地图)都在一个列表中传递给视图。效果很好,我的后期操作可以分离出不同的地图,分别处理每个地图及其图块。
该视图基本上是:
- Tile 1 CheckBox: Keep[]?
- Tile 2 CheckBox: Keep[]?
- Tile 3 CheckBox: Keep[]?
... and so on
无需担心它们来自什么地图。地图信息仍然存在(它在每个图块对象上),我只是在“发布”操作中对其进行了处理,以将它们正确地分成地图。
但是现在,我想添加一个功能来说给定地图的图块列表是否完整。我的目标是一个复选框-看起来像这样:
Map Identifier map1 CheckBox: Complete? []
- Tile 1 for map1 CheckBox: Keep[]?
- Tile 2 for map1 CheckBox: Keep[]?
- ... and so on
Map Identifier map2 CheckBox: Complete? []
-Tile 1 for map2 CheckBox: Keep[]?
- ... ect
我不知道每次尝试将有多少块图块或地图。
所以我试图做的是创建一个新的ViewModel:
public class MultipleMapIdentifiers
{
[Display(Name = "Map: ")]
public string MapIdentifier { get; set; }
public List<TileInformation> TileInformationList{ get; set; }
[Display(Name = "Full Run? ")]
public bool FullRun { get; set; }
}
然后,在返回Review视图之前,我简单地遍历了所有提交的图块,获取了不同的MapIdentifiers,然后遍历图块以查找具有相同mapID的图块,并将它们放在此视图对象的列表中
然后,我使用新的编辑器模板创建了新的视图。
首先,我只是在MultipleMapIdentifiers EditorTemplate中使用了@foreach循环来显示每个图块。展示他们很棒。调用Post时返回空列表。
因此,我第二次尝试为每个项目调用局部视图-仍然是MultipleMapsIdentifiers EditorTemplate中的Foreach循环,但是它为我跳过的TileInformation调用了一个模板,该模板可以正确用于编辑器复选框。请记住-如果我们要保留此图块或将其作为坏/重复的图块丢弃,则每个TileInformation都有其自己的复选框。
这也只会将空的Tile列表返回到Post Action。
有什么方法可以实现吗?如何获取带有其复选框的列表,并将其原封不动地返回到“发布操作”中,以便在添加到数据库之前删除不希望保留的列表?
答案 0 :(得分:0)
万一有人在搜索并降落在这里:
我结束了向普通模型中添加几个[NotMapped]属性,包括第一个布尔值。如果第一个标记为true,则它将显示地图标识符字符串和其他内容,否则,它将仅使用剃刀中的隐藏字段将数据推入其余模型版本。
@if (Model.First)
{
<div class="row mb-3 bg-info rounded">
<div class="col-sm-2 font-weight-bold border-bottom border-light mb-2 align-items-center">
@Html.DisplayNameFor(a => a.MapIdentifier)
</div>
<div class="col-sm-7 font-italic text-truncate border-bottom border-light mb-2 align-items-center">
<div class="display-field">
@Html.DisplayFor(a => a.MapIdentifier)
</div>
<div class="editor-field">
@Html.HiddenFor(a => a.MapIdentifier)
@Html.ValidationMessageFor(a => a.MapIdentifier)
</div>
</div>
<div class="col-sm-3 border-bottom border-light mb-2">
<p class="text-center"><span>@Html.CheckBoxFor(a => a.FullRun)</span> <b>Was this a Complete Run?</b></p>
<p class="text-center"><span>@Html.CheckBoxFor(a => a.MapPointsRecorded)</span> <b>Recording Map Points?</b></p>
</div>
<div class="editor-field">
@Html.HiddenFor(a => a.First)
@Html.ValidationMessageFor(a => a.First)
</div>
</div>
}
else
{
<div class="editor-field">
@Html.HiddenFor(a => a.MapIdentifier)
@Html.ValidationMessageFor(a => a.MapIdentifier)
</div>
}
可能不是最优雅的解决方案,但目前仍然有效。