2009-10-06 34 views
2

好吧,Asp.Net MVC /實體框架。避免標籤湯?

我有一個新的MVC項目,它使用實體框架。我現在正在吐出郵件(這是一個公告板樣式部分),現在取決於一些條件因素,表輸出中的行必須具有不同的類風格。

傳遞到頁面從控制器的模型是實體模型(調用消息,幷包含相同的字段數據庫)

我們獲得該行的風格在我做了以下內容,

<% 
       int i = 0; 
       foreach (var message in ViewData.Model.MessageList) 
       { 
        string className = "rowEven"; 

        if (i % 2 == 0) { className = "rowOdd"; } 
        if (message.Deleted) { className = "deleted"; } 
        if (message.AuthorisedBy == null) { className = "notAuth"; } 
        if (message.Deleted) { className = "deleted"; } 

      %> 
        <tr class="<%=className%>"> 
         <td><%= Html.CheckBox("mc1")%></td> 
         <td> 
          <%= Html.ActionLink(message.Title, "Details", new { id = message.MessageID })%> 
         </td> 
         <td>User Name Here</td> 
         <td><%= Html.Encode(message.PublishDateTime.ToString())%></td> 
        </tr>     
      <% 
        i++; 
       } 
      %> 

這是非常醜陋的,必須有更好的方式做到這一點,有什麼建議?

+0

只是想補充一點,你可以同時使用一個ViewModel和的HtmlHelper。一些東西(轉換數據)屬於ViewModel,一些東西(選擇特定的CSS類)屬於HTML助手。你甚至可能想要得到一個只有一個MessageItemViewModel並且只顯示一行的部分 - 這有助於你開始做Ajax的時候。 – 2009-10-06 10:23:22

+0

我們有很多Ajax很快就會做,所以我喜歡你所說的話。你能提供一些參考或一些例子的鏈接嗎?我們對MVC非常陌生。 – LiamB 2009-10-06 10:35:01

+0

這需要一些額外的努力,但切換視圖引擎可能會讓您更清楚地瞭解頁面內容。看看Spark View Engine:http://sparkviewengine.com/ – alexandrul 2009-10-06 12:23:07

回答

5

這是最肯定的表現邏輯和視圖是它屬於。不過,你最好是移動CSS類選擇代碼視圖助手,這將同時接受MessageMessageList

public static string GetMessageCssClassName(this /* Don't remember :) */, Message message, MessageList messages) 
{ 
    var cssClassName = messages.IndexOf(message) % 2 == 0 ? 
     "rowOdd" : "rowEven"; 

    if(message.Deleted) cssClassName = "deleted"; 
    if(message.AuthorisedBy == null) cssClassName = "notAuth"; 
    if(message.Deleted) cssClassName = "deleted"; 
} 

現在你可以調用你的<tr class="Html.GetMessageCssClassName(...)">,擺脫i計數器:

<% foreach (var message in ViewData.Model.MessageList) { %> 
    <tr class="<%= Html.GetMessageCssClassName(message, ViewData.Model.MessageList) %>"> 
     <td><%= Html.CheckBox("mc1")%></td> 
     <td> 
      <! -- Remaining stuff here --> 
<% } %> 
+0

您擴展GetMessageCssClassName(這個HtmlHelper助手,:)可能還想添加一個註釋添加擴展方法以及如何增加名稱空間。 – 2009-10-06 10:17:42

+1

它還爲您提供了將單元測試添加到包含邏輯的表示層部分的選項,否則可能無法獲得圍繞它進行的自動化測試,這可能是一個不錯的獎勵。 – 2009-10-06 10:35:22

1

如何添加一些輔助方法?您可以編寫自己的擴展方法基礎HtmlHelper類,所以你可以寫這樣的:

... 
<tr class="<%= Html.GetMessageCssClass(i, message) %>"> 
... 
2

我會建議使用此模型 - 視圖 - 視圖模型。這使您可以將很多邏輯封裝在視圖模型類中,然後只需在視圖模型上調用方法,而不是將邏輯內聯。這將使它看起來像這樣...

 <% foreach (var messageViewModel in ViewData.Model.MessageList) { %> 
       <tr class="<%=message.RowClass%>"> 
        <td><%= Html.CheckBox("mc1")%></td> 
        <td> 
         <%= Html.ActionLink(message.Title, "Details", new { id = message.MessageID })%> 
        </td> 
        <td>User Name Here</td> 
        <td><%= Html.Encode(message.PublishedAt)%></td> 
       </tr>     
     <% } %> 

當你結束了多了很多類,你得到更可讀的標記和您的應用程序更可測試。它將您的視圖變成視圖模型的一個非常簡單的窗口。視圖模型然後封裝視圖僅需要的任何邏輯和屬性。

迴應你的評論here是一篇文章,解決MVC中的模型 - 視圖 - 視圖模型模式。你只需要用一堆屬性和/或方法創建一個類,然後用你需要的所有東西填充這個類。然後將該類傳遞給您的視圖,而不是直接傳遞模型。您甚至可以使用AutoMapper或其他映射框架自動將模型映射到視圖模型。

+0

嗨傑克, 我喜歡這個想法,你可以給我們怎麼做到這一點furthor的例子? – LiamB 2009-10-06 10:18:23

+0

更新了帖子來回答你的問題。 – 2009-10-06 11:46:18

0

正如很多人已經提到過的,您可以爲您的Namespace.Site項目(mvc項目)中的Message類編寫擴展方法。

喜歡的東西:

public static class Extensions 
{ 
    public static string CssClass(this Message message,int counter) 
    { 
     if (i % 2 == 0) 
      return "rowOdd"; 
     else if (message.AuthorisedBy == null) 
      return "notAuth";  
     else if (message.Deleted) 
      return "deleted"; 

     return "rowEven"; 
    } 
} 

用法:

<tr class="<%=message.CssClass(i)%>"> 
    <td><%= Html.CheckBox("mc1")%></td> 
    <td><%= Html.ActionLink(message.Title, "Details", new { id = message.MessageID })%></td> 
    <td>User Name Here</td> 
    <td><%= Html.Encode(message.PublishDateTime.ToString())%></td> 
</tr>