Передача нескольких результирующих наборов в представление из контроллера в ASP.NET MVC? - PullRequest
0 голосов
/ 08 февраля 2009

Итак, у меня есть контроллер, настроенный следующим образом:

using NonStockSystem.Models;

namespace NonStockSystem.Controllers
{
    [Authorize(Users = "DOMAIN\\rburke")]
    public class AdminController : Controller
    {    
        private NonStockSystemDataContext db = new NonStockSystemDataContext();

        public ActionResult Index()
        {
            var enumProducts = from p in db.Products select p;
            ViewData["Title"] = "Administration";
            return View(enumProducts.ToList());
        }
    }
}

Представление «Индекс» на контроллере администратора просто перечисляет продукты в системе и позволяет нам щелкнуть продукт, чтобы просмотреть / отредактировать / удалить его. Действительно просто. Однако у каждого продукта есть CategoryID, который сообщает нам, в какой категории он хранится в отдельной таблице.

(очень упрощенный) текущий вид:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="NonStockSystem.Views.Home.Admin" %>
<%@ Import Namespace="NonStockSystem.Models" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

<%
foreach (Product p in (IEnumerable)ViewData.Model)
{ %>

    <%=p.Name.ToString() %> (<a href="/Admin/Edit/<%=p.ID.ToString() %>">Edit</a> - <a href="/Admin/Delete/<%=p.ID.ToString() %>">Delete</a>)<br />

<%
} %>   

</asp:Content>

На данный момент это нормально, так как в системе есть только 10 или 15 продуктов, пока я разрабатываю и тестирую ее, однако, как только я разверну ее, будет приблизительно. 300 товаров в базе данных. Я в порядке с отображением их всех на одной странице, однако я хотел бы использовать ссылки (a href = "# category") так же, как это делает Википедия, так что в верхней части страницы я могу получить список категорий, и когда вы нажимаете один он приводит вас в соответствующий раздел страницы. Итак, мой взгляд в этом случае будет выглядеть так:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="NonStockSystem.Views.Home.Admin" %>
<%@ Import Namespace="NonStockSystem.Models" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

<ul>
<%
foreach (Category c in (IEnumerable)ViewData.Model)
{ %>
    <li><a href="#<%=c.Name.ToString() %>"><%=c.Name.ToString() %></a></li>
<%
} %>
</ul>

<hr />

<%
foreach (Category c in (IEnumerable)ViewData.Model)
{ %>
    <% // Display the category name above all products from that category %>
    <h2><a name="<%=c.Name.ToString() %>"><%=c.Name.ToString() %></a></h2>

    <% // Need to limit the following foreach to grab only products in this category
    foreach (Product p in (IEnumerable)ViewData.Model)
    { %>
        <%=p.Name.ToString() %> (<a href="/Admin/Edit/<%=p.ID.ToString() %>">Edit</a> - <a href="/Admin/Delete/<%=p.ID.ToString() %>">Delete</a>)<br />
    <%
    } %>
} %>

</asp:Content>

Во-первых, я не совсем уверен, что это «правильный» способ сделать это, поэтому я определенно открыт для предложений о другом способе ведения дел, но если это путь, то мне нужно знать, как (1) передать два набора результатов в представление (Товары и Категории) и (2) пройти через подмножество Продуктов в каждом цикле foreach, отбирая только те, что в соответствующей категории?

Ура!

1 Ответ

3 голосов
/ 08 февраля 2009

У вас есть две альтернативы. Во-первых, вы можете создать модель только для просмотра, которая состоит из коллекций Products и Categories. Во-вторых, вы можете передать одну или обе модели в ViewData вместо того, чтобы устанавливать их в качестве модели для страницы.

public class CategoryProduct
{
    public IEnumerable<Product> Products { get; set; }
    public IEnumerable<Category> Categories {get; set; }
}

....

return View( new CategoryProduct { Products = products,
                                   Categories = categories } );

Это позволяет вам использовать строго типизированную модель представления и получать intellisense, но стоит дополнительный класс, который вам необходимо поддерживать.

или (один вариант)

ViewData["categories"] = categories;
return View( products );

Это требует приведения ViewData для категорий, чтобы вы могли использовать их строго типизированными. Продукты в данном случае это модель. Вы можете поменять их или поместить оба в ViewData.

Что касается вашего подхода, я в порядке. Один из вариантов - сделать страницу постраничной, чтобы не все категории существовали на одной странице, чтобы уменьшить длину страницы. У вас все еще были бы все категории, перечисленные в верхней части, но некоторые могут потребовать обратной передачи вместо того, чтобы получить новую страницу данных. Это, вероятно, немного сложно, но ускорит время загрузки, когда число продуктов растет. Другой способ сделать это - использовать детализацию. Сначала выберите категорию, затем только продукты в этой категории. Они также могут быть разбиты на страницы. Я думаю, что это более типично для сайтов типа Amazon, Buy.com и т. Д. Они также допускают дополнительную фильтрацию (категория является только верхним уровнем).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...