简体   繁体   English

如何传递IEnumerable <SelectListItem> 收集到MVC部分视图,每个请求只有一个数据库查找

[英]How to pass IEnumerable<SelectListItem> collection to a MVC Partial View with only one database lookup per request

Suppose that given a partial view for an html table, there exists a nested partial view for each table row such as the following: 假设给定html表的局部视图,每个表行都有一个嵌套的局部视图,如下所示:

Outer Partial View 外部局部视图

<table>
<thead>
  <tr>
    <th>Item Name</th>
    <th>Cost</th>
    <th>Category</th>
  </tr>
</thead>
<tbody>
@for (int i = 0; i < Model.PurchaseItems.Count; i++)
{ 
  @Html.Partial("_PurchaseItemsDetail", Model.PurchaseItems[i])
}     
</tbody>
</table>

Inner Partial View, NOTE: this partial view may used multiple times by the outer view in a single request, however it may also be used just once if requested using AJAX 内部局部视图,注意:在一个请求中,外部视图可以多次使用此局部视图,但是如果使用AJAX请求它​​也可以只使用一次

<tr id="@Model.ID">
  <td>@Html.TextBoxFor(x => x.ItemName)</td>
  <td>@Html.TextBoxFor(x => x.Cost)</td>
  <td>
    @Html.DropDownListFor(x => x.Category, CATEGORY_COLLECTION)
  </td>
</tr>

Problem : Given this inner view that is intended to be flexible, what is the best way to query the database and temporarily store the IEnumerable<SelectListItem> collection to be used with the dropdown? 问题 :鉴于此内部视图旨在灵活,查询数据库和临时存储要与下拉列表一起使用的IEnumerable<SelectListItem>集合的最佳方法是什么? Ways that I can think of: 我能想到的方法:

Method 1 : This seems to be the easiest , however it feels like it violates MVC principles. 方法1这似乎是最简单的 ,但感觉它违反了MVC原则。 Evaluate in the inner partial view and store in ViewData collection in such a way that the database is only hit once: 在内部局部视图中进行评估并以这样的方式存储在ViewData集合中:数据库只被命中一次:

    @{
     if (ViewData["Categories"] == null)
     {
       ViewData["Categories"] = API.GetCategories();
     }
    }

then later in the view 然后在视图中

  <td>
    @Html.DropDownListFor(x => x.Category, ViewData["Categories"])
  </td>

This is nice because the view takes care of itself as far as determining how to populate its containing dropdown. 这很好,因为只要确定如何填充其包含的下拉列表,视图就会自行处理。 It does not rely on the view model. 它不依赖于视图模型。

Method 2 : Same as above, except set the ViewData in the various controller methods that return the inner partial view. 方法2 :与上面相同,除了在返回内部局部视图的各种控制器方法中设置ViewData。 This way seems to be more in line with MVC best practices, however it seems more tedious and confusing to maintain given that each controller method needs to set the ViewData properly, as well as create the necessary view model. 这种方式似乎更符合MVC最佳实践,但是考虑到每个控制器方法需要正确设置ViewData以及创建必要的视图模型,维护似乎更加繁琐和混乱。

Method 3 : This seems the most work, the hardest to maintain, but most in accordance with MVC principles . 方法3这似乎是最多的工作,最难维护,但大多数符合MVC原则 Avoid using the ViewData entirely, but store a reference to the collection along with the other properties in the partial view model. 避免完全使用ViewData,但在部分视图模型中存储对集合的引用以及其他属性。 It would be the responsibility of the controller to create the collection, and then store a reference in each of the table rows' view models. 控制器负责创建集合,然后在每个表行的视图模型中存储引用。

public class PurchaseItemModel
{
  public string ItemName { get; set; }
  public decimal Cost { get; set; }
  public string Category { get; set; }

  // add this
  public IEnumberable<SelectListItem> Categories { get; set; }
}

and in each controller that server the inner view 并在服务于内部视图的每个控制器中

// if dealing with multiple rows (GET)
IEnumerable<SelectListItem> collection = API.GetPurchaseItemList();
foreach (PurchaseItemModel pim in OuterModel.PurchaseItemModels)
{
  pim.Categories = collection;
}

or 要么

// if dealing with a single row (Ajax)
purchaseItem.Categories = API.GetPurchaseItemList();

then later in the view 然后在视图中

  <td>
    @Html.DropDownListFor(x => x.Category, x.Categories)
  </td>

Perhaps this is just subjective question, but it seems like there would be a best practice for this type of situation. 也许这只是主观问题,但似乎这种情况会有最好的做法。 Any thoughts? 有什么想法吗?

Go ahead and create a ViewModel Class such as 继续创建一个ViewModel类,如

public class PurchaseItemViewModel
{
  public string ItemName { get; set; }
  public decimal Cost { get; set; }
  public string Category { get; set; }
  public IEnumberable<Category> Categories { get; set; }

  public PurchaseItemViewModel(PurchaseItemModel item, List<Category> categories)
  {
       //initialize item and categories
  }
}

In the controller get all the items then get all the categories then set the Purchase items to the ViewModel and set the categories. 在控制器中获取所有项目,然后获取所有类别,然后将购买项目设置为ViewModel并设置类别。 So you will pass the ViewModel Class to the view. 因此,您将ViewModel类传递给视图。

Method 3 is the way to go - but don't make it so complicated. 方法3是要走的路 - 但不要让它变得那么复杂。 Have two properties - a PurchaseItem property and a Categories property. 有两个属性 - PurchaseItem属性和Categories属性。 Then instantiate per iteration and set the properties. 然后实例化每次迭代并设置属性。

Loose example: 宽松的例子:

<table>
<thead>
  <tr>
    <th>Item Name</th>
    <th>Cost</th>
    <th>Category</th>
  </tr>
</thead>
<tbody>
@for (int i = 0; i < Model.PurchaseItems.Count; i++)
{ 
    var vm = new PurchaseItemsDetailViewModel()
        {
            PurchaseItem = Model.PurchaseItems[i],
            Categories = Model.CategoriesSelectList // or whatever holds the categories select list
        };
  @Html.Partial("_PurchaseItemsDetail", vm)
}     
</tbody>
</table>


<tr id="@Model.PurchaseItem.ID">
  <td>@Html.TextBoxFor(x => x.PurchaseItem.ItemName)</td>
  <td>@Html.TextBoxFor(x => x.PurchaseItem.Cost)</td>
  <td>
    @Html.DropDownListFor(x => x.PurchaseItem.Category, x.Categories)
  </td>
</tr>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将IEnumerable模型传递给MVC中的局部视图 - How to pass an IEnumerable model to a partial view in MVC IEnumerable的 <SelectListItem> 在C#mvc中 - IEnumerable<SelectListItem> in C# mvc 如何传递 IEnumerable 数组<int>在 ASP.NET MVC 中从一个视图到另一个视图正确吗? - How to pass array of IEnumerable<int> from one view to another in ASP.NET MVC correctly? 如何在MVC中使用IEnumerable模型将数据从控制器传递到视图? - How to pass Data from Controller to View with IEnumerable Model in MVC? 如何将项添加到IEnumerable SelectListItem - How to add item to IEnumerable SelectListItem 在MVC 5的视图中同时编辑IEnumerable项目集合 - Edit IEnumerable collection of items simultaneously in a View in MVC 5 当两个部分视图都包含在 ASP.NET MVC 中的同一父视图中时,如何将数据列表从一个部分视图传递到另一个部分视图? - How to pass a list of data from one partial view to another partial view, when both partial views are contained in a same parent view in ASP.NET MVC? 异常“没有类型为&#39;IEnumerable的ViewData项 <SelectListItem> ” MVC - Exception “There is no ViewData item of type 'IEnumerable<SelectListItem>” MVC 如何从控制器到视图传递一行数据,而不是IEnumerable &lt;&gt; - How to pass one row of data from controller to view , not as IEnumerable<> 如何在MVC中循环中将模型数据从视图传递到局部视图 - How to pass model data from view to partial view in loop in MVC
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM