0

所以我有一个控制器设置如下:

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());
        }
    }
}

Admin 控制器上的 Index 视图仅列出系统中的产品,并允许我们单击产品以查看/编辑/删除它。真的很简单。然而,每个产品都有一个 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 个产品,但是一旦我部署它,就会有大约 15 个产品。数据库中有 300 种产品。我可以将它们全部显示在一个页面上,但是我想使用 (a href="#category") 链接,就像 Wikipedia 在页面顶部使用的那样,我可以拥有类别列表,当您单击一个它将您带到页面的适当部分。因此,在这种情况下,我的观点将如下所示:

<%@ 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 循环中的产品子集,仅获取适当类别中的产品?

干杯!

4

1 回答 1

3

你有两个选择。首先,您可以创建一个包含 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 } );

这允许您使用强类型视图模型并获得智能感知,但需要额外维护一个类。

或(一个选项)

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

这需要为类别转换 ViewData,以便您可以使用强类型。在这种情况下的产品是模型。您可以交换这些或将两者都放入 ViewData。

至于你的方法,我可以接受。一种替代方法是对其进行分页,以便并非所有类别都存在于同一页面上以降低页面长度。您仍然会在顶部列出所有类别,但有些可能需要回发来获取新的数据页面。这可能有点复杂,但是当产品数量增加时会加快加载时间。另一种方法是使用向下钻取。首先选择一个类别,然后只显示该类别中的产品。这些也可以被分页。我认为这更像是亚马逊、Buy.com 等网站的典型做法。它们还允许额外的过滤(类别只是顶级)。

于 2009-02-08T13:48:54.007 回答