新视图或部分视图

时间:2011-11-10 14:33:06

标签: c# asp.net-mvc partial-views asp.net-mvc-4

情况就是这样:

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

但这是我的问题(我已经被困2天了): 做这个的最好方式是什么?转到新页面或使用部分视图。因为我一直在尝试两者并且显然我必须做错事,因为似乎都没有。我不需要任何像这样的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);
}

3 个答案:

答案 0 :(得分:3)

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

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

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

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

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

Ajax:http://www.plus2net.com/php_tutorial/ajax_drop_down_list.php

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

答案 1 :(得分: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个Guids弄脏你的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 */
}

如果您要在其他页面上呈现订单详细信息,您需要将订单详细信息放在部分视图中,这样您就不会复制任何标记。如果它只在这里呈现,那么你真的没有理由在这个视图中没有你的标记。

答案 2 :(得分:1)

我会建议这样的事情:

  1. 你有一个带动作的控制器。行动需要两个 参数,一个用你的guid,另一个用另一个id
  2. 您的“主视图”列出了您的商品
  3. 在您的控制器中,添加一个其他操作,这次只有一个 参数,一个id
  4. 添加另一个视图,但这一次是部分视图,列出了您的视图 其他项目
  5. 操作1在viewmodel中放置一个包含项目的列表,并在一个可选的id中放置一些其他项目。

    动作3在viewmodel

    中放置一个包含其他项目的列表

    操作1呈现视图2,操作3呈现视图4.视图2呈现,如果视图模型如此,则执行操作3.

    基本上,当没有选择特定项目时,执行链将如下所示: 1 =&gt; 2 =&gt;完成

    但是当选择一个项目时,链将是这样的: 1 =&gt; 2 =&gt; 3 =&gt; 4

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

相关问题