【问题标题】:Get data from a foreach partial view in razorview从 Razor 视图中的 foreach 局部视图获取数据
【发布时间】:2012-08-05 22:15:57
【问题描述】:

我是 MVC3 和 C# 的新手。

这是我目前的模型

@model Reports.ViewModels.ContentViewModel
<div>Total Hours: </div>

foreach (var user in Model.Users.ToList()) {
   @Html.Partial("_DirectReports", user)
}

这很好用,然后我在这些局部视图中有 HTML,它使用另一个 @model 呈现我想要的一切。 问题是我想将所有数据加在一起。

我想在 foreach 之外创建一个 var foreach 将数据插入 var 并在 foreach 完成后返回,如下所示

@model Reports.ViewModels.ContentViewModel

@{var Total = 0}
foreach (var user in Model.Users.ToList()) {
   @Html.Partial("_DirectReports", user)
   //@Total is assigned a value in the partial view
}

<div>Total Hours: @Total</div>

如果这是可能的,那就太好了

【问题讨论】:

    标签: c# asp.net-mvc-3 razor partial-views


    【解决方案1】:

    恐怕您正在混合 MVC 模式中的职责。这就是为什么你正在为此苦苦挣扎。您应该使用视图模型。这不是你的观点应该处理的事情。因此,只需在您的 ContentViewModel 视图模型上定义一个 Total 属性,并让您的控制器操作完成为其分配值的工作。然后:

    @model Reports.ViewModels.ContentViewModel
    
    foreach (var user in Model.Users.ToList()) {
       @Html.Partial("_DirectReports", user)
    }
    
    <div>Total Hours: @Model.Total</div>
    

    在 ASP.NET MVC 中,视图不负责计算任何内容。视图的职责是仅以视图模型的形式显示为其准备的数据。

    【讨论】:

      【解决方案2】:

      这就是你想要的。

      @model Reports.ViewModels.ContentViewModel
      
      @{
      int Total = 0;
      foreach (var user in Model.Users.ToList()) {
         @Html.Partial("_DirectReports", user)
         //@Total is assigned a value in the partial view
         Total = 5;
      }
      
      <div>Total Hours: @Total</div>
      }
      

      将给出:总小时数:5

      【讨论】:

      • 您只需要定义变量的范围。就是这样。
      • 没有在部分中定义总计:)。 John H 的回答可能是最好的。谢谢
      【解决方案3】:

      把逻辑和你的观点混合在一起,你会走下一个滑坡。 MVC 旨在减少不同层(模型、视图和控制器)之间的耦合,以使代码更易于维护和测试等。

      所以让我们试着清理一下。首先,Total 是一条数据,这意味着它应该是模型的一部分:

      public class ContentViewModel 
      {
          public List<User> Users { get; set; }
          public int TotalHours
          {
              get
              {
                  return Users.Sum(u => u.Hours); // Assuming User has an Hours property
              }
          }
      }
      

      然后控制器应该处理模型的创建并为其提供数据。像这样的:

      public ActionResult Index()
      {
          ContentViewModel viewModel = new ContentViewModel();
          viewModel.Users = db.Users.ToList();
      
          return View(viewModel);
      }
      

      现在你有了你需要的数据,你可以减少很多你当前在视图中使用的逻辑(比如使用 foreach 和Total var):

      @model Reports.ViewModels.ContentViewModel
      
      @Html.DisplayFor(m => m.Users)
      
      <div>Total Hours: @Model.TotalHours</div>
      

      Html.DisplayForHtml.EditorFor 使用所谓的显示/编辑器模板,它们会自动为您循环遍历集合,为每个项目呈现一个模板。为了对ContentViewModel 使用此功能,您需要创建一个显示模板。为此,您需要在视图所在的位置创建一个文件夹,并将其命名为DisplayTemplates。例如,如果您的视图是~/Views/Home/Index.cshtml,则需要创建文件夹:~/Views/Home/DisplayTemplates

      右键单击该文件夹以添加新视图。在出现的对话框中,您要制作一个强类型视图,选择您要传递给模板的类型(在我的示例中,User 是类型而不是List&lt;User&gt;),使其成为局部视图并确保将其命名为与类型相同的名称(同样,User)。一旦有了模板,就可以像在普通视图中一样使用 HTML 帮助器。像这样的:

      @model Models.User
      
      @Html.LabelFor(m => m.Name)
      @Html.DisplayFor(m => m.Name)
      

      现在您已将事物分解为可管理的块。如果您想了解有关使用显示/编辑器模板的更多信息,我强烈建议您阅读有关该主题的 Brad Wilson's article series。即使它是为 MVC 2 编写的,它仍然适用。

      【讨论】:

      • 感谢您的出色回复,非常感谢。
      猜你喜欢
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多