Asp.Net MVC / Entity Framework. Избежать тега суп? - PullRequest
2 голосов
/ 06 октября 2009

Хорошо,

У меня есть новый проект MVC, в котором используется структура сущностей. Я выкладываю сообщения (это раздел стиля доски объявлений), теперь в зависимости от некоторых условных факторов строка в выводе таблицы должна иметь другой стиль класса.

Модель, которая передается на страницу из контроллера, является моделью сущности (Called Messages и содержит те же поля, что и база данных)

Теперь, чтобы получить стили строк, я сделал следующее:

<%
               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++;
               } 
           %>

Что довольно уродливо, должен быть лучший способ сделать это, какие-либо предложения?

Ответы [ 4 ]

5 голосов
/ 06 октября 2009

Это наиболее определенная логика представления, и представление принадлежит ему. Однако вам лучше переместить этот код выбора класса CSS в помощник вида, который будет принимать как Message, так и MessageList:

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 counter:

<% foreach (var message in ViewData.Model.MessageList) { %>
    <tr class="<%= Html.GetMessageCssClassName(message, ViewData.Model.MessageList) %>">
        <td><%= Html.CheckBox("mc1")%></td>
        <td>
            <! -- Remaining stuff here -->
<% } %>
2 голосов
/ 06 октября 2009

Я бы рекомендовал использовать модель-вид-вид-модель здесь. Это позволяет вам инкапсулировать большую часть вашей логики в классе модели представления, тогда вы просто вызываете методы в своей модели представления, а не помещаете свою логику в линию. это бы выглядело примерно так ...

       <%  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>                 
       <% } %>

Хотя у вас гораздо больше классов, вы получаете намного более читаемую разметку, и ваше приложение гораздо более тестируемо. Он превращает ваш вид в очень простое окно на вашу модель вида. Затем модель представления инкапсулирует любую логику и свойства, которые необходимы исключительно представлению.

В ответ на ваш комментарий здесь - статья, в которой рассматривается модель модели - представление - просмотр модели в MVC. Вам просто нужно создать класс с кучей свойств и / или методов и заполнить этот класс всем, что вам нужно. Затем передайте класс вашему представлению вместо того, чтобы передавать модель напрямую. Вы даже можете использовать AutoMapper или другую инфраструктуру сопоставления для автоматического сопоставления ваших моделей с вашими моделями представления.

1 голос
/ 06 октября 2009

Как насчет добавления некоторых вспомогательных методов? Вы можете написать свои собственные методы расширения для базового класса HtmlHelper, чтобы вы могли написать что-то вроде:

...
<tr class="<%= Html.GetMessageCssClass(i, message) %>">
...
0 голосов
/ 06 октября 2009

Как уже упоминалось, вы можете просто написать метод расширения для вашего Message класса, который находится внутри вашего проекта Namespace.Site (проект mvc).

Что-то вроде:

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> 
...