4

这是这种情况:

我有一个 ASP.NET MVC 4 应用程序。当我运行应用程序时,我转到一个页面,控制器上的 Index - 操作将 Guid 作为 id - 参数。使用该 ID,我从数据库中获取项目列表并将其放入 ViewModel。这个 ViewModel 被传递给一个 View,它将所有项目作为 ActionLink 列出(必要时可以更改)。当我单击其中一个项目时,我想根据所选链接的 id 获取其他项目的列表,并在第一个列表旁边显示这个新列表。

但这是我的问题(以及我被困两天的地方):最好的方法是什么?转到新页面或使用局部视图。因为我一直在尝试两者,显然我一定做错了一些事情,因为似乎没有任何工作。我不需要任何 AJAX 的东西或这样的助手,只需要一个正确的方法来完成这件事...... :)

提前致谢!

更新:我已经拥有的代码

看法

@foreach (var order in Model.Orders)
{
    <p>@Html.ActionLink(order.Name,
                        "OrderItems",
                        "OrdersController",
                        new { id = order.Id },
                        null)
    </p>
}

@if (Model.Detail != null)
{
    @Html.Partial("_OrderItemsByOrder", Model)
}

控制器

public ActionResult Index(Guid id)
{
    var orders = Services.GetOrders(id);
    var viewModel = new OrdersViewModel { Orders = orders };
    return View(viewModel);
}

public ActionResult OrderItems(Guid id, OrdersViewModel model)
{
    var orderItems = Services.GetOrderLines(id);
    var viewModel = new OrdersViewModel
    {
        Orders = model.Orders,
        Detail = new OrderDetailViewModel { OrderItems = orderItems }
    };
    return PartialView(viewModel);
}
4

3 回答 3

3

您可能(为了用户可用性)想要使用 AJAX 并从 AJAX 响应中下拉“其他项目”列表(可能是 JSON,如果您真的想避免使用 JavaScript,则可能是部分 HTML 页面)

如果您真的不想使用 AJAX,您可以拉出所有项目和所有“其他项目”并将它们最初存储在“隐藏”字段中,然后执行两个选择框。

http://www.plus2net.com/javascript_tutorial/dropdown-list.php

示例:http ://www.plus2net.com/javascript_tutorial/dropdown-list-demo.php

老实说,我会选择 AJAX 选项,除非人们经常使用每个下拉菜单,或者选项的数量非常有限。

阿贾克斯:http ://www.plus2net.com/php_tutorial/ajax_drop_down_list.php

只是想指出,它不需要是用于选择/填充的下拉框,您只需更改代码即可填充 div 或您想要的任何元素:)

于 2011-11-10T15:02:30.013 回答
2

有几种方法可以实现这样的主/详细页面,确实没有最好的方法来做到这一点。AJAX 可能是最优雅和用户友好的,但它绝不是“正确”的答案。

查看您发布的代码,您可以做的最简单的事情就是拥有一个操作方法和一个视图。

public class OrdersViewModel
{
    public IEnumerable<Order> Orders { get; set; }
    public OrderItems SelectedOrderItems { get; set; }
}

public ActionResult Orders(Guid id, Guid? orderId)
{
    var model = new OrdersViewModel();
    model.Orders = Services.GetOrders(id);

    if (orderId != null)
    {
        model.SelectedOrderItems = Services.GetOrderLines(orderId);
    }

    return View(model);
}

这种相当基本的方法的缺点是,您可能有 2 个 Guid 弄脏了您的 Url,并且此示例未验证 orderId 是否实际上由(用户?) Id 拥有 - 无论第一个 Guid 代表什么。你可以用几行代码来处理这个问题。

如果您不介意更改 Url,则更优雅的处理方法是坚持使用第二种操作方法。我希望您可以从详细信息本身确定订单详细信息的“所有者”,或者以某种不需要您将其传递给操作方法的方式。这有助于确保您的视图仅显示来自正确母版的详细信息。

public ActionResult OrderDetails(Guid id /*the id of the order*/)
{
    var orderLines = Services.GetOrderLines(id);

    var model = new OrdersViewModel();
    //ideally you could get to the "owner id" of the order from the order lines itself
    //depending on how your domain model is set up
    model.Orders = Services.GetOrders(orderLines.Order.OwnerId); 
    model.SelectedOrderItems = orderLines;

    return View("Orders", model); //render the same view as the Orders page if like
}

您在问题中列出的观点可以大致保持不变。呈现代表所有订单的操作链接。如果模型中有订单详细信息,则呈现订单详细信息:

@if (Model.SelectedOrderItems!= null)
{
    /* markup here or a render partial call */
}

如果您在其他页面上呈现订单详细信息,您需要将订单详细信息放在局部视图中,这样您就不会复制任何标记。如果它只在此处呈现,那么您确实没有理由无法在此视图中正确使用您的标记。

于 2011-11-10T18:45:27.657 回答
1

我会建议这样的事情:

  1. 你有一个带有动作的控制器。该操作需要两个参数,一个带有您的 guid,一个带有其他 id 的可选参数
  2. 您有列出您的项目的“主视图”
  3. 在你的控制器中,添加另一个动作,这次只有一个参数,一个 id
  4. 添加另一个视图,但这次是部分视图,其中列出了您的其他项目

动作 1 在视图模型中放置一个包含项目的列表,以及一个可选的 id 以呈现一些其他项目。

动作 3 在视图模型中放置一个包含其他一些项目的列表

动作 1 渲染视图 2,动作 3 渲染视图 4。视图 2 渲染,如果视图模型如此,动作 3。

基本上,当没有选择特定项目时,执行链将是这样的:1 => 2 => Done

But when an item is selected the chain will be like this: 1 => 2 => 3 => 4

(当然,这只是一种做事方式..)

于 2011-11-10T15:34:55.823 回答