假設給定了html表的部分視圖,則存在每個錶行的嵌套局部視圖,如下所示:如何將IEnumerable <SelectListItem>集合傳遞給每個請求只有一個數據庫查詢的MVC部分視圖
外局部視圖
<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>
內局部視圖,注意:此局部視圖也可以由外視圖在單個請求中多次使用,然而,它也可以僅一次如果使用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>
問題:鑑於此內部視圖旨在靈活,查詢數據庫並臨時存儲要與下拉列表配合使用的IEnumerable<SelectListItem>
集合的最佳方法是什麼?
方法1:我可以想辦法這似乎是最簡單的,但感覺就像它違反了MVC的原則。評估在ViewData的集合內局部視圖和存儲這樣的數據庫只命中一次:
@{
if (ViewData["Categories"] == null)
{
ViewData["Categories"] = API.GetCategories();
}
}
後來在視圖
<td>
@Html.DropDownListFor(x => x.Category, ViewData["Categories"])
</td>
這是很好的,因爲視圖照顧只要確定如何填充其包含的下拉菜單。它不依賴於視圖模型。
方法2:除了在返回內部局部視圖的各種控制器方法中設置ViewData外,與上面相同。這種方式似乎更符合MVC最佳實踐,但是,考慮到每個控制器方法需要正確設置ViewData並創建必要的視圖模型,它似乎更加繁瑣和混亂。
方法3:這似乎大部分工作,最難維護,但大多數按照MVC原則。避免完全使用ViewData,而是在部分視圖模型中存儲對集合的引用以及其他屬性。控制器負責創建集合,然後在每個表格行的視圖模型中存儲引用。
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; }
}
並且在每個控制器,服務器內視圖
// if dealing with multiple rows (GET)
IEnumerable<SelectListItem> collection = API.GetPurchaseItemList();
foreach (PurchaseItemModel pim in OuterModel.PurchaseItemModels)
{
pim.Categories = collection;
}
或
// if dealing with a single row (Ajax)
purchaseItem.Categories = API.GetPurchaseItemList();
然後在後面的視圖
<td>
@Html.DropDownListFor(x => x.Category, x.Categories)
</td>
也許,這僅僅是主觀的問題,但它似乎就在那裏將是這種情況的最佳做法。有什麼想法嗎?
這不是一個很好的問題 - 而不是描述模糊,抽象的情景,描述你的具體* * *的問題與支持代碼*。 –
@AntP,我編輯了我的問題。也許你會發現確定的缺點已被修復。 –
幹得好,現在問題好多了。 –