【问题标题】:MVC How to load a view and a partial view from one controllerMVC 如何从一个控制器加载视图和局部视图
【发布时间】:2020-07-09 21:07:08
【问题描述】:

我有一个控制器,它返回一个视图,该视图中有一个表格,其中填充了有关订单的信息

public class HomeController : Controller 
{
        public IActionResult OrderTracking()
        {
            List<WebOrder> orderList = SuperDAL.GetWebOrders();
            foreach(WebOrder order in orderList)
            {
                order.Parts = SuperDAL.GetPartsForWebOrder(order.ID);
            }

            return View(orderList);
        }
}

订单跟踪视图

@model List<WebOrder>

        <table id="orderTable" class="orderTable">
            <thead>
                <tr>
                    <th>Priority</th>
                    <th>Web Order Number</th>
                    <th>Order Number</th>
                    <th>Company</th>
                    <th>Status</th>
                    <th>Due Date</th>
                    <th>Date Received</th>
                    <th>Customer</th>
                    <th>Order Cost</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var webOrder in Model)
                {
                    <tr data-ID="@webOrder.ID">
                        @*The tds with data-date are storing the date contained
                            within the tds in ISO date format. This value is
                            being pulled in JavaScript to avoid having
                            messy string formating in JS for date comparisons*@
                        <td class="@webOrder.getPriority().ToLower()">@webOrder.getPriority()</td>
                        <td>@webOrder.WebOrderNumber</td>
                        <td>@webOrder.ExternalOrderNumber</td>
                        <td>@webOrder.CompanyName</td>
                        <td>@webOrder.getOverallStatus()</td>
                        <td data-date="@webOrder.dueDateISOFormat()">@webOrder.getDueDate()</td>
                        <td data-date="@webOrder.dateReceivedISOFormat()">@webOrder.DateReceived</td>
                        <td>@webOrder.CustomerName</td>
                        <td>@webOrder.OrderCost</td>
                    </tr>
                }
            </tbody>
    @*The Order Modal*@
    <div id="orderModal" class="modal">
        @*Modal Content*@
    </div>

表格中的每一行都有一个点击事件处理程序,当触发该事件处理程序时,将向控制器发送一个 ajax 调用,以返回包含订单详细信息的部分视图。

$.ajax({
            type: "POST",
            url: "/WebOrder/Details/",
            data: { 'id': orderID },
            dataType: "html",
            success: function (response) {

                $("#orderModal").html(response);

                //modal.style.display = "block";
                //Does more stuff

            },
            failure: function (response) {
                alert(response.responseText);
            },
            error: function (response) {
                alert(response.responseText);
            }
        });
public class WebOrderController : Controller
    {
        [HttpPost]
        public IActionResult Details(int id)
        {
            WebOrder webOrder = SuperDAL.GetWebOrder(id);
            webOrder.Parts = SuperDAL.GetPartsForWebOrder(webOrder.ID);
            return PartialView("ModalPartial", webOrder);
        }

    }

Details 控制器返回的部分视图被放入OrderTracking 视图的orderModal div 中。

默认情况下,在我的 CSS 中,我隐藏了该 div。单击表中的一行时,在 ajax 调用的成功部分中,我取消隐藏样式为模式的 div,该模式在当前页面上弹出,显示有关所选订单的更多信息。成功部分还将其他事件应用于模态。

现在我要解决的问题是我希望能够通过在 URL 栏中导航到 OrderTracking 控制器并让它拉起 OrderTracking 视图来显示带有部分视图的模式以及模态和局部视图。 URL 类似于 domain/Home/OrderTracking/5 ,其中 5 是订单的 ID。

这样做的原因是最终目标是能够有一个二维码,当二维码阅读器扫描时会拉出订单,因此二维码将包含带有订单号的 url。

目前,我很难想象我将如何实现这一目标。我认为有几种方法可以实现这一点,但我认为它们是不正确的。

我想到实现这一点的一种方法是让一个重载的OrderTracking 控制器使用GET 请求。该控制器将调用Details 控制器并返回OrderTracking 视图,但虽然可能可行,但很可能不是正确的方法。

另一个问题是,使用 URL 方法时,我无法像在设置事件处理程序和其他内容的 ajax 调用中那样从控制器触发 jQuery 或 JavaScript。我想解决这个问题的一种方法是在局部视图中包含一个 $(document).ready 函数。

如果我需要澄清任何事情,请告诉我。

【问题讨论】:

    标签: asp.net-mvc asp.net-core


    【解决方案1】:

    执行此操作的一种简单方法是将 orderID 传递给您的 View 并触发表格中相应订单的点击事件。这将触发您的发布请求并显示带有部分视图的模式。即

    创建一个视图模型:

    public class OrderViewModel{
       public int? OrderID { get; set; }
       public List<WebOrder> Orders { get; set; }
    }
    

    改变你的行动:

    public class HomeController : Controller 
    {
            public IActionResult OrderTracking(int? orderID)
            {
                List<WebOrder> orderList = SuperDAL.GetWebOrders();
                foreach(WebOrder order in orderList)
                {
                    order.Parts = SuperDAL.GetPartsForWebOrder(order.ID);
                }
    
                return View(new OrderViewModel(){ OrderID = orderID, Orders = orderList});
            }
    }
    

    触发点击事件:

    <script>
       $(function(){
           if(@Model.OrderID !=null){
               //trigger click event
           }
       })
    </script>
    

    【讨论】:

      【解决方案2】:

      如果你想这样做,你可以直接在视图中添加局部视图,就像Siddanth说的那样,将OrderId传递给你的视图。这样你甚至不需要点击按钮来添加局部视图。你可以这样改变: 订单模型:

      public class OrderModel
          {
              public WebOrder SelectedOrder { get; set; }
              public List<WebOrder> Orders { get; set; }
          }
      

      控制器:

      public IActionResult OrderTracking(int? orderId)
          {
              OrderModel orderModel = new OrderModel();
              List<WebOrder> orderList = SuperDAL.GetWebOrders();
              foreach (WebOrder order in orderList)
              {
                  order.Parts = SuperDAL.GetPartsForWebOrder(order.ID);
              }
              orderModel.Orders = orderList;
              orderModel.SelectedOrder = new WebOrder();
              if (orderId != null)
              {
                  WebOrder webOrder = SuperDAL.GetWebOrder(id);
                  orderModel.SelectedOrder = webOrder;
                  
              }
              return View(orderModel);
          }
      

      换网


      订单:

      public int? ID { get; set; }
      

      查看:

      <div id="orderModal" class="modal" >
          @await Html.PartialAsync("ModalPartial", @Model)
      </div>
      <script type="text/javascript">
              $(function () {
      
                  if (@Model.SelectedOrder.ID!=null) {
                      $("#orderModal").modal("show");
                  }
              })
          </script>
      

      【讨论】:

        最近更新 更多