这可能是一个棘手的问题,但它就在这里。
假设我有一个主要视图,我们称之为MainView.cshtml
。
现在,MainView.cshtml
有一个名为MainViewModel.cs
的专用视图模型,它包含一个变量Model.ExampleItems
,该变量是类ExampleItem
的IEnumerable。
现在假设我也有一个名为 _PartialView.cshtml
的部分视图,其视图模型只是 ExampleItem
。
好的,这就是我卡住的地方。 MainView.cshtml
可以动态调用_PartialView.cshtml
以便用户可以创建新ExampleItem
。如何将每个用户创建的ExampleItem
保存到MainViewModel
的 IEnumerable of ExampleItems?
下面是一些示例代码
MainView.cshtml
@model Models.ViewModels.MainViewModel
@foreach (var item in Model.ExampleItems)
{
await Html.RenderPartialAsync("_PartialView", item);
}
<button id="AddExampleItem" type="button" class="btn btn-primary">Add Example Item</button>
_PartialView.cshtml
@model Models.ExampleItem
<input asp-for="VariableOne" />
<input asp-for="VariableTwo" />
<input asp-for="VariableThree" />
如何将^^^保存到原始Model.ExampleItems
中?
你在这里有两条路。无论哪种方式,为了绑定已发布的ExampleItem
,表单字段必须以格式命名 ExampleItems[N].Property
。因此,要做到这一点,您可以执行以下操作:
-
使用
for
循环,而不是foreach
并传递HtmlFieldPrefix
:@foreach (var i = 0; i < Model.ExampleItems; i++) { var viewData = new ViewDataDictionary(ViewData); viewData.TemplateInfo.HtmlFieldPrefix = "ExampleItems[" + i.ToString + "]"; await Html.RenderPartialAsync("_PartialView", Model.ExampleItems[i]); }
您还需要将
ExampleItems
设置为List<ExampleItem>
而不是IEnumerable<ExampleItem>
否则将引发枚举两次的异常(count 然后是 for 循环(。 -
为
ExampleItem
创建编辑器模板,然后利用EditorFor
。只需在~/Views/Shared/EditorTemplates/ExampleItem.cshtml
处创建一个视图,然后将部分代码放在那里。然后在您的主视图中,您只需执行以下操作:@Html.EditorFor(m => m.ExampleItems)
Razor 将智能地确定你是否向其传递了一个集合,并为集合中的每个项目呈现编辑器模板。此外,重要的是,它将具有集合的完整上下文,因此它将使用正确的名称前缀,以便所有内容在发布时正确绑定。