【问题标题】:How to save partial view viewmodel items in main view viewmodel with Razor?如何使用 Razor 在主视图视图模型中保存部分视图视图模型项?
【发布时间】:2016-07-18 12:56:31
【问题描述】:

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

假设我有一个主视图,我们称之为MainView.cshtml

现在,MainView.cshtml 有一个名为 MainViewModel.cs 的专用 ViewModel,其中包含一个变量 Model.ExampleItems,它是类 ExampleItem 的一个 IEnumerable。

现在假设我还有一个名为 _PartialView.cshtml 的局部视图,其 ViewModel 只是 ExampleItem

好的,这就是我卡住的地方。 MainView.cshtml可以动态调用_PartialView.cshtml,这样用户就可以创建一个新的ExampleItem。如何将每个用户创建的 ExampleItem 保存到 MainViewModel 的 ExampleItems 的 IEnumerable?

这是一些示例代码

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 中?

【问题讨论】:

  • IEnumerable of ExampleItems 主要用于查询.. 要保存,您可能需要List 或数据库表。每次您的用户在您的_PartialView.cshtml 中创建ExampleItem 时,将其存储在数据库中。然后,每次获取 ExampleItems 时,只需要从 DB 表中查询即可。
  • 你想在哪里做'添加项目'?客户端还是服务器端?
  • @Dandy 我忘了包括这部分。这一切都包装在一个表单中......所以基本上在用户添加了所有新的示例项目之后,他们可以点击提交,然后它将被保存到我们的外部数据库中。但是,当 ExampleItems 在 POST 上传递回控制器时,它是一个空列表
  • 当然,如果这符合您的问题,您可以通过 ajax 异步发布您的部分视图数据。如果你愿意,我可以举个例子。
  • 你能再显示一些代码吗?如何用户adds all of the new ExcampleItems?您是否使用 ajax 或常规形式发布方法发布新添加的 ExampleItems

标签: c# asp.net-mvc asp.net-mvc-4 razor asp.net-mvc-5


【解决方案1】:

你有两条前进的道路。无论哪种方式,为了绑定发布的ExampleItems,表单字段必须以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&lt;ExampleItem&gt; 而不是IEnumerable&lt;ExampleItem&gt;,否则您将引发两次枚举异常(计数然后for 循环)。

  2. ExampleItem 创建一个编辑器模板,然后使用EditorFor。只需在~/Views/Shared/EditorTemplates/ExampleItem.cshtml 创建一个视图,然后将您的部分代码放在那里。然后在你的主视图中你会这样做:

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

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

【讨论】:

  • 非常感谢您提到编辑器模板 - 我完全忘记了它们。这很好用,看起来比我的 foreach 循环干净得多。但是,我将如何将新的 ExampleItem 添加到原始的 ExampleItems 列表中?在提交表单时,新的 ExampleItem(s) 将被完全删除
  • 我假设您正在通过 JavaScript 动态添加新项目的字段,如果我不得不猜测,可能是通过获取部分的 AJAX 请求。在这种情况下,字段名称的前缀将不正确,这就是模型绑定器丢弃它们的原因。我建议使用 Knockout 或 Angular 之类的工具来生成字段,以便您可以根据输入的名称属性在 JavaScript 数组中的位置正确索引它们。
  • 呃,是的,我只是看起来你是对的。我以前从未使用过,所以我将看看 Knockout。感谢所有的帮助,伙计。我将继续并将其标记为答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
相关资源
最近更新 更多