新视图或部分视图

发布于 2024-12-14 18:11:46 字数 1343 浏览 0 评论 0原文

情况是这样的:

我有一个 ASP.NET MVC 4 应用程序。当我运行应用程序时,我会转到一个页面,控制器上的 Index - 操作采用 Guid 作为 id - 参数。使用该 id,我从数据库中获取项目列表并将其放入 ViewModel 中。该 ViewModel 被传递到一个 View,该 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);
}

This is the situation:

I have an ASP.NET MVC 4 application. When I run the application I go to a page and the Index - action on the controller takes a Guid as id - parameter. With that id I get a list of items from a database and put it into a ViewModel. This ViewModel is passed to a View which lists all of the items as an ActionLink (could be changed if necessary). When I click one of the items I want to get a list of other items, based on the id of the selected link, and show this new list right next to the first list.

But this is my question (and where I've been stuck for 2 days):
What is the best way to do this? Go to a new page or use a partial view. Because I have been trying a bit of both and clearly I must've done some things wrong because none seemed to work. I don't need any AJAX-stuff or helpers like that, only a correct way to get this done... :)

Thanks in advance!

Update: the code that I already have

View

@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)
}

Controller

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

以往的大感动 2024-12-21 18:11:54

我建议这样:

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

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

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

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

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

但是当选择一个项目时,链将如下所示:
1 => 2=> 3=> 4

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

I would suggest something like this:

  1. You have a controller with an action. The action takes two
    parameters, one with your guid and one optional with some other id
  2. You have your "mainview" that lists your items
  3. In your controller, add one other action, this time with only one
    parameter, an id
  4. Add another view, but this time, a partial view, that lists your
    other items

Action 1 puts a list with items in the viewmodel, and an optional id to render some other items.

Action 3 puts a list with some other items in the viewmodel

Action 1 renders view 2 and action 3 renders view 4. View 2 renders, if the viewmodel says so, action 3.

Basically, when no specific item is selected then execution chain will be like this:
1 => 2 => Done

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

(Of course, this is just one way of doing things..)

坦然微笑 2024-12-21 18:11:53

有多种方法可以实现这样的主页面/详细信息页面,但确实没有最好的方法。 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 */
}

如果您要在其他页面上渲染订单详细信息,则需要将订单详细信息放在部分视图中,这样就不会重复任何标记。如果它仅在此处呈现,那么您确实没有理由不能在此视图中正确显示标记。

There are several ways you could achieve a master/detail page like this, there really is no best way to do this. AJAX may be the most elegant and user friendly, but it's by no means the "right" answer.

Looking at the code you posted, the simplest thing you could do is have one action method and one view.

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

The drawback with this rather basic approach is that you'll have possibly 2 Guids dirtying up your Url and this example doesn't verify that the orderId is actually owned by the (user?) Id - whatever the first Guid represents. You could handle this with a few lines of code though.

A more elegant way of handling this, if you don't mind your Url changing, is to stick with the second action method. I would hope you can determine the "owner" of an order detail from the detail itself, or in some way that wouldn't require you to pass this into the action method. This helps ensure that your view only shows details from the right master.

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
}

Your view as listed in your question can largely stay the same. Render the action links that represent all of the orders. Then render the order details if there is one in the model:

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

If you are rendering the order details on other pages, you'll want to put your order details in a partial view so you don't duplicate any of your markup. If it's only rendered here, then there's really no reason why you couldn't have your markup right in this view.

把梦留给海 2024-12-21 18:11:51

您可能(为了用户可用性)想要使用 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 选项,除非人们经常使用每个下拉菜单,或者如果选择的数量非常有限。

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

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

You'll likely (for user usability) want to use AJAX and pull down the list of the "other items" from an AJAX response (JSON likely, or Partial HTML page if you really want to avoid javascript)

If you really don't want to use AJAX, you could pull all of the items, and all of the "other items" and store them in "hidden" fields initially and do two select boxes.

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

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

I would honestly go with the AJAX option though unless people will be using each of the dropdowns often, or if the amount of options is very limited.

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

And just want to point out, it doesn't need to be dropdown boxes that are used to select / populate, you'd just have to change the code around to populate a div or whatever element you want :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文