如何使用 Razor 在主视图视图中保存部分视图模型项



这可能是一个棘手的问题,但它就在这里。

假设我有一个主要视图,我们称之为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 。因此,要做到这一点,您可以执行以下操作:

  1. 使用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 循环(。

  2. ExampleItem创建编辑器模板,然后利用EditorFor 。只需在 ~/Views/Shared/EditorTemplates/ExampleItem.cshtml 处创建一个视图,然后将部分代码放在那里。然后在您的主视图中,您只需执行以下操作:

    @Html.EditorFor(m => m.ExampleItems)
    

    Razor 将智能地确定你是否向其传递了一个集合,并为集合中的每个项目呈现编辑器模板。此外,重要的是,它将具有集合的完整上下文,因此它将使用正确的名称前缀,以便所有内容在发布时正确绑定。

最新更新