2011-05-15 119 views
4

考慮這個方案:如何解耦關係MVC數據

我想爲Northwind數據庫構建一個MVC應用程序。我想有一個視圖,列出一些命令,我​​想創建CustomerID和EmployeeID的鏈接以及[OrderDetails]的詳細信息鏈接,以便當用戶單擊任何鏈接時,相關數據將出現在同一頁面中。

我的問題是如何將這些相互關聯的數據分解成顯示頁面中相關數據的視圖和控制器,以及負責信息各個部分的控制器。

另外,如何配置此示例的路由?

<table width="500px"> 
    <tr> 
     <th></th> 
     <th> 
      OrderID 
     </th> 
     <th> 
      CustomerID 
     </th> 
     <th> 
      EmployeeID 
     </th> 
     <th> 
      OrderDate 
     </th> 
     <th> 
      RequiredDate 
     </th> 
     <th> 
      ShippedDate 
     </th> 
     <th> 
      ShipVia 
     </th>    
     <th> 
      OrderDetails 
     </th> 
    </tr> 

<% foreach (var item in Model) { %> 

    <tr> 
     <td> 
      <%: Html.ActionLink("Edit", "Edit", new { id=item.OrderID }) %> | 
      <%: Html.ActionLink("Details", "Details", new { id=item.OrderID })%> | 
      <%: Html.ActionLink("Delete", "Delete", new { id=item.OrderID })%> 
     </td> 
     <td> 
      <%: item.OrderID %> 
     </td> 
     <td> 
      <%: item.CustomerID %> 
     </td> 
     <td> 
      <%: item.EmployeeID %> 
     </td> 
     <td> 
      <%: String.Format("{0:g}", item.OrderDate) %> 
     </td> 
     <td> 
      <%: String.Format("{0:g}", item.RequiredDate) %> 
     </td> 
     <td> 
      <%: String.Format("{0:g}", item.ShippedDate) %> 
     </td> 
     <td> 
      <%: item.ShipVia %> 
     </td>    
     <td> 
      <%: Html.ActionLink("OrderDetails", "GetOrderDetails", new { id = item.OrderID })%> 
     </td> 
    </tr> 

<% } %> 

</table> 

<p> 
    <%: Html.ActionLink("Create New", "Create") %> 
</p> 

<div> 
    <p> 
     <% Html.RenderPartial("GetOrderDetails"); %> 
    </p> 
    <%--<uc1:GetOrderDetails ID="GetOrderDetails1" runat="server" />--%> 
</div> 

和訂單細節部分視圖:

<table> 
    <tr> 
     <th></th> 
     <th> 
      OrderID 
     </th> 
     <th> 
      ProductID 
     </th> 
     <th> 
      UnitPrice 
     </th> 
     <th> 
      Quantity 
     </th> 
     <th> 
      Discount 
     </th> 
    </tr> 

<% foreach (var item in Model) { %> 

    <tr> 
     <td> 
      <%: Html.ActionLink("Edit", "Edit", new { id=item.OrderID }) %> | 
      <%: Html.ActionLink("Details", "Details", new { id=item.OrderID })%> | 
      <%: Html.ActionLink("Delete", "Delete", new { id=item.OrderID })%> 
     </td> 
     <td> 
      <%: item.OrderID %> 
     </td> 
     <td> 
      <%: item.ProductID %> 
     </td> 
     <td> 
      <%: String.Format("{0:F}", item.UnitPrice) %> 
     </td> 
     <td> 
      <%: item.Quantity %> 
     </td> 
     <td> 
      <%: item.Discount %> 
     </td> 
    </tr> 

<% } %> 

</table> 

<p> 
    <%: Html.ActionLink("Create New", "Create") %> 
</p> 

global.asax中:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 



     routes.MapRoute(
      "Default2", // Route name 
      "{controller}/{action}/{OrderId}/{CustomerID}", // URL with parameters 
      new { controller = "NorthwindOrders", action = "Index", OrderId = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults 
     ); 

     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
     ); 
    } 

鑑於這種結構;點擊任何OrderDetails鏈接時,如何在訂單列表中顯示訂單詳細信息?

而且,爲什麼會顯示這樣的URL,當我點擊訂單明細鏈接:

http://localhost:49444/NorthwindOrders/GetOrderDetails?id=10250 

我想要的網址顯示是這樣的:

http://localhost:49444/NorthwindOrders/GetOrderDetails/10250 
+0

通過在視圖中試圖解決這個問題,還爲時不晚。你不應該在控制器中更早解決它。視圖只是顯示數據,所以使用正確的模型,甚至視圖模型,視圖變成了一個簡單的解釋。 – 2011-05-19 11:00:29

回答

2

爲了您的路由問題:

如果設置了像這樣的路線:

routes.MapRoute(
     "orderdetails", // Route name 
     "{controller}/{action}/{id}", // URL with parameters 
     new { controller = "NorthwindOrders", action = "GetOrderDetails", id = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults 
    ); 

它將建立在你想要時尚的URL。

(或者,您也可以將參數您GetOrderDetails行動重命名爲string OrderId,它會發現格式的URL你想要的方式的路線。)

至於你的主要問題:

如何根據點擊鏈接「動態」加載頁面上的內容

有兩種方法可以解決這個:

  • 後回頁面。
  • AJAX /動態加載頁面上HTML中的數據和元素。

在回來後的場景:

在這種情況下你的鏈接都會去那個構建,其中包括來自主頁的orderlist示範行動,併爲你點擊的具體訂單的詳細信息您可以使用該訂單的細節填充模型。然後你的ActionResult返回是相同的視圖(或者至少看起來相同),你的視圖將使用PartialView Html幫助器來呈現細節。

OrderViewModel:

public class OrderViewModel 
{ 
    public IList<Order> Orders {get;set;} 
    public OrderDetail Details {get;set;} 
} 

訂單查看。ASPX:

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<OrderViewModel>" %> 
<%:Html.DisplayFor(m=>m.Orders)%> <%-- Displays the Table above listing orders --%> 
<%:Html.DisplayFor(m=>m.Details)%> <%-- Displays your custom view of the details --%> 

OrderController:

... 
public ActionResult List() 
{ 
    var model = new OrderViewModel { Orders = GetAllOrders(), Details = null }; 
    return View("OrderView", model); 
} 

public ActionResult GetOrderDetails(string OrderId) 
{ 
    var model = new OrderViewModel { Orders = GetAllOrders(), Details = GetOrder(OrderId) }; 
    return View("OrderView", model); 
} 
... 

在阿賈克斯的情況:

阿賈克斯的情況基本上是除了你隱藏在Ajax調用服務器往返,然後同在ajax調用的返回數據中重新加載頁面,或只是一個帶有你想要的HTML內容(或JSON)的div。

Ajax方法的優點是,您可以在不同的控制器上爲您想要更新的頁面的各個部分指定不同的操作。

+0

謝謝,但我怎麼可以在同一頁面加載細節?H – Arian 2011-05-18 04:29:00

+0

沒有看到你的控制器和模型(S )很難說......你可以用AJAX做,也可以用post-backs ......我會擴展我的答案。 – 2011-05-18 04:30:40

+0

謝謝,但我的主要問題仍然存在。在聲明我們有Inherits =「System.Web.Mvc.ViewPage >」,這告訴我們什麼對象我們的觀點depend.ok我們如何可以顯示從Order Object繼承的訂單詳情(OrderDetails對象)? – Arian 2011-05-18 04:51:39

1

構建您的訂單列表中的網址使用Url.Action查看。這將根據您的路由配置建立鏈接,所以當您更改您的配置時,您將不會斷開鏈接。

至於出現在同一頁上,您可以使用某種形式的ajax。使用jQuery你有這樣的事情在你的訂單列表視圖連入客戶點擊鏈接:

<script type="text\javascript"> 
    $('#result').load('<%= Url.Action("CustomerDetails", "Customer", 
      new { customerId = ViewModel["customerId"] }) %>'); 
</script> 

<div id="result"/> 

沒有Ajax需要的參數,你的順序列出控制器,如「displayCustomerId =」,這將告訴順序列出以便渲染客戶細節:

<% if(ViewData["displayCustomerId"] != null) %> 
    <% Html.RenderAction("CustomerDetails", "Customer", 
      new { customerId = ViewData["displayCustomerId"] }) %> 
<% } %> 

兩種技術都允許一個單獨的控制器,以用於服務起來用於列出訂單視圖內的相關數據。

+0

謝謝,但這導致一個視圖使用多個控制器和一個控制器使用多個views.How解決這個問題? – Arian 2011-05-16 13:00:07

2

尼瑪,
您可以通過局部的觀點做或渲染動作,和JSON顯示數據
基本的例子是這裏的例子: http://www.asp.net/mvc/tutorials/iteration-7-add-ajax-functionality-cs

或非常流行的選擇是對的任務顯示動作在jquery.dialog()

取決於你要繼續 CPO


修訂有什麼辦法:

我的不好。 從邏輯上來看,它是這樣的:
它只取決於你,你想走哪條路。 (從我的角度來看)分離邏輯

好處是:

  1. 簡單理解爲控制器僅用於如行動相關:訂單
  2. 可以在更多地方使用,如果你需要
  3. 容易測試只有小件物品,例如一個測試用例/夾具控制器僅訂單
  4. 有用的更復雜的項目

在另一方面

  1. 把一切都在一個控制器和分裂按地區邏輯
  2. Eveything在一起,很容易看到其他的方法和他們做什麼

希望這是什麼你要找的
CPO

+0

謝謝,但我的問題是如何解耦控制器和視圖。 – Arian 2011-05-17 04:13:35

+0

難道你不能在你想渲染的對象周圍添加表單併發布到不同的位置嗎?如Html.BeginForm(您的路由規範在這裏) – cpoDesign 2011-05-17 07:08:13

+0

我想你誤解了我的問題。我想知道是否應該爲Orders,Customers和OrderDetails創建一個控制器? – Arian 2011-05-17 08:11:15