Как я могу избежать тега суп с MVC? - PullRequest
14 голосов
/ 29 декабря 2011

Я читал это в своем стремлении оправдать MVC над не-mvc, как обычный старый php (не используя MVC, даже классический asp можно использовать, хотя и болезненно):

http://www.codinghorror.com/blog/2008/07/web-development-as-tag-soup.html

И я не могу найти ответ.Я думаю, это неизбежно, чтобы получить суп супДа, я знаю, что MVC разделяет модель и контроллер, но когда вы переходите к представлению, все просто отвратительно.Я могу читать испускаемый html так же хорошо или лучше, чем теговый суп.

Я не буду использовать модульное тестирование, так что это не так уж важно.Я не уверен, как я могу когда-либо избежать уродливого представления, теперь независимо от того, как я получаю это с mvc или просто испуская html.

Я не вижу, что легче поддерживать представление со всей странной кодировкой (и это код), чем использование response.write "<table>".

пример: Работа с ASP.NET MVC "tag tag"

Ответ Арнисом (без обидили кто-то еще), исправляет ужасный код в вопросе, но для меня это все еще выглядит плохо или, по крайней мере, не то, что я ожидаю.Для меня эти угловые скобки с таким же успехом могли быть <% %> или <?php ?>.

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

Это в основном касается представления.Не о том, какой язык лучше для какого или чей движок шаблонов самый лучший (все они имеют одинаковые тенденции к разметке).

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

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

edit: Кажется, все ориентировано наконкретная структура вместо плана.Я вижу некоторую проницательность, но, в конце концов, кажется, нет другого пути, кроме дисциплины.Спасибо всем за ответы.

Ответы [ 7 ]

19 голосов
/ 05 января 2012

Взгляните на использование Razor механизма просмотра, включенного в MVC 3 . Также постарайтесь сохранить всю логику в классе Controller и построить модель на основе того, что отображается в View .

  • Razor - один из очевидных способов избежать супа тегов, так как нет необходимости в каких-либо тегах <% и %> - просто @ до того, как ваш код и механизм представления сработают где заканчивается C # и начинается HTML.

    <span class="name">@Model.Name</span>
    

    Четные циклы и операторы по-прежнему выглядят сексуально в .cshtml файле с Razor и этим волшебным @ символом.

    @if(shouldDisplayDiv) {
        <div id="mydiv">Div is displayed!</div>
    }
    
    
    @foreach(User user in Model.Friends) {
        <a href="@user.Url"><img src="@user.ImageUrl" title="@user.Name" /></a>
    }
    

    Razor также обрабатывает HTML-кодировку для вас по умолчанию, поэтому ваше представление не будет полно Html.Encode вызовов. (Примечание: если вам нужно вывести HTML, вы можете использовать вспомогательный метод Html.Raw).

  • Размещение вашей логики в контроллере в идеале устранит необходимость в больших кодовых блоках в представлении. Постарайтесь, чтобы объекты модели содержали все динамические данные для представления в точности так, как они будут отображаться в представлении. Старайтесь не иметь какого-либо кода C # в вашем представлении вообще (бессмысленно, но если это цель, посмотрите, как близко вы можете добраться до нее!).

  • Частичные виды могут красиво разделить различные части вашего вида (но старайтесь не использовать их слишком много). Вы также можете передать разные объекты модели для каждого частичного вида, что, как я считаю, может быть полезно для некоторых больших циклов или что-то вроде flair .

  • HTML Helpers также очень полезны (спасибо subkamran) . Здесь есть аналогичное понятие с частичными представлениями, упомянутыми выше, но HtmlHelpers немного отличается, потому что вы указываете параметры метода (и их типы), в отличие от частичных представлений, которые вы можете передавать один объект Model. Вот хороший пример того, как их реализовать . Опять же, они могут выглядеть очень аккуратно в вашем cshtml коде.

     <div class="specialdiv">@Html.SomeMethod(Model, "String", 5)</div>
    
  • MVC * на стороне клиента - это еще один вариант, который настоятельно рекомендуется при разработке веб-приложений с интенсивным использованием AJAX. Следуя логике в контроллере , вы будете использовать клиентскую MVC-инфраструктуру, такую ​​как Backbone.js, для аккуратного шаблонирования HTML, и использовать jQuery .ajax() для общения с вашим контроллером. Отличная практика для разделения слоя презентации, оставляя вам красивую разметку View!

Я придерживаюсь этих маленьких рекомендаций, и это работает для меня как обаяние. Хорошая, чистая HTML-разметка со случайным символом @. Очень прост в обслуживании (ну, по крайней мере, представления есть!).

РЕДАКТИРОВАТЬ: Обратите внимание, что все эти пункты включены в ASP.NET MVC 3 и являются «передовым опытом» для Microsoft. Нет необходимости устанавливать какие-либо дополнительные фреймворки, плагины или дополнения, чтобы придерживаться этих рекомендаций.

5 голосов
/ 10 января 2012

Есть причина, по которой MVC набирает обороты.Несмотря на то, что к представлению добавлено несколько тегов, гораздо понятнее, если логика правильно обрабатывается в контроллере, к которому она должна принадлежать.

Также важно понимать, что на самом деле представляет собой MVC: http://en.wikipedia.org/wiki/Model-view-controller. Преимущества, которые вы получаете от него, - более чистое разделение и простота замены.

Учтите это.У вас есть клиент, который хочет, чтобы вы написали приложение, которое поддерживает как традиционные браузеры, так и мобильные браузеры.С шаблоном MVC действительно легко заставить контроллер обнаруживать платформу и изменять отображаемое представление.Если все сделано правильно, замена одного представления на другое должно быть очень простым процессом.

У меня есть 7-летний опыт написания приложений в ASP.NET Forms.Как только я переключился на MVC и начал понимать MVC, я понял, что никогда не вернусь.Взгляды чище, отладка проще, а логика более очевидна.Последнее написанное мной приложение использует MVC и jQuery, имеет 3000 пользователей в день и стало образцовым сайтом, для которого теперь написаны все наши сайты.

Наш клиент попросил нас добавить мобильную поддержку на наш сайт.Поскольку мы выбрали MVC в нашей реализации, нам потребовалась 1 неделя, чтобы добавить полную поддержку мобильных устройств.Мы не могли бы сделать это так быстро и использовать код настолько эффективно, если бы мы делали это в ASP.NET Forms.

Хотя пример кода из http://www.codinghorror.com/blog/2008/07/web-development-as-tag-soup.html выглядит ужасно, вы когда-нибудь смотрели на ASP.NET GridView?HTML ужасен.В приведенном вами примере также показан кто-то, кто мог бы поработать, чтобы очистить свои взгляды.Вот сравнение gridview и MVC с Razor:

GridView:

<asp:datagrid id="voucherGrid" runat="server" CssClass="dg" CellPadding="2" AutoGenerateColumns="False" DataKeyField="cx_nbr" 
        Width="800px" AllowPaging="True" AllowSorting="True" PageSize="20" OnPageIndexChanged="voucherGrid_PageIndexChanged" 
        OnSortCommand="voucherGrid_SortCommand" OnItemDataBound="voucherGrid_ItemDataBound">
        <SelectedItemStyle CssClass="dgSelectItem"></SelectedItemStyle>
        <AlternatingItemStyle CssClass="dgAlternateItem"></AlternatingItemStyle>
        <ItemStyle CssClass="dgNormalItem"></ItemStyle>
        <HeaderStyle ForeColor="White" CssClass="dgHeader"></HeaderStyle>

        <Columns>
            <asp:TemplateColumn HeaderText="Image">
                <ItemStyle HorizontalAlign="Center"></ItemStyle>
                <ItemTemplate>
                    <asp:HyperLink id="voucherImageLink" Target="_blank" runat="server">Image</asp:HyperLink>                                               
                </ItemTemplate>
            </asp:TemplateColumn>
            <asp:BoundColumn DataField="cx_voucher_nbr" SortExpression="cx_voucher_nbr" HeaderText="Call #">
                <ItemStyle HorizontalAlign="Center"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_pkup_datetime" SortExpression="cx_pkup_datetime" HeaderText="Date" DataFormatString="{0:MM/dd/yyyy}">
                <ItemStyle HorizontalAlign="Center"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_pass_name" SortExpression="cx_pass_name" HeaderText="Passenger">
                <ItemStyle Wrap="False"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_pkup_address" SortExpression="cx_pkup_address" HeaderText="Pick-Up">
                <ItemStyle Wrap="False"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_dest_address" SortExpression="cx_dest_address" HeaderText="Destination">
                <ItemStyle Wrap="False"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_trip_miles" SortExpression="cx_trip_miles" HeaderText="Miles" DataFormatString="{0:N2}">
                <ItemStyle HorizontalAlign="Right"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_pkup_datetime" SortExpression="cx_pkup_datetime" HeaderText="Time" DataFormatString="{0:t}">
                <ItemStyle HorizontalAlign="Center"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_vch_wait_time_amt" SortExpression="cx_vch_wait_time_amt" HeaderText="Wait" DataFormatString="{0:C}">
                <ItemStyle HorizontalAlign="Right"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_vch_other_amt" SortExpression="cx_vch_other_amt" HeaderText="Other" DataFormatString="{0:C}">
                <ItemStyle HorizontalAlign="Right"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_vch_admin_charge_amt" SortExpression="cx_vch_admin_charge_amt" HeaderText="Admin Charge" DataFormatString="{0:C}">
                <ItemStyle HorizontalAlign="Right"></ItemStyle>
            </asp:BoundColumn>
            <asp:BoundColumn DataField="cx_vch_fare_amt" SortExpression="cx_vch_fare_amt" HeaderText="Rate" DataFormatString="{0:C}">
                <ItemStyle HorizontalAlign="Right"></ItemStyle>
            </asp:BoundColumn>
        </Columns>

        <PagerStyle ForeColor="White" CssClass="dgPager" Mode="NumericPages"></PagerStyle>
    </asp:datagrid>

Razor:

<table id="voucherGrid" class="dg" style="width: 800px;">
   <th class="dgHeader">
      <td>Image</td>
      <td>Call #</td>
      <td>Date</td>
      <td>Passenger</td>
      <td>Pick-Up</td>
      <td>Destination</td>
      <td>Miles</td>
      <td>Time</td>
      <td>Wait</td>
      <td>Other</td>
      <td>Admin Charge</td>
      <td>Rate</td>
   </th>
   @foreach(var voucher in Model.Vouchers) {
   <tr>
      <td>@voucher.Image</td>
      <td>@voucher.CallNum</td>
      <td>@voucher.Date</td>
      <td>@voucher.Passenger</td>
      <td>@voucher.PickUp</td>
      <td>@voucher.Destination</td>
      <td>@voucher.Miles</td>
      <td>@voucher.Time</td>
      <td>@voucher.Wait</td>
      <td>@voucher.Other</td>
      <td>@voucher.AdminCharge</td>
      <td>@voucher.Rate</td>
   </tr>
   }
</table>

Скажите, что выглядит проще для понимания?Для меня гораздо чище иметь дело с тегами html и несколькими дополнительными тегами @ или <%.</p>

Вы также упомянули, что нет необходимости в модульном тестировании.Я бы пересмотрел эту мысль.Модульное тестирование может быть чрезвычайно полезно для выявления проблем до того, как они возникнут на производственной площадке.

2 голосов
/ 29 декабря 2011

туда и обратно.Опять и опять.Сырой HTML.Dreamwearver.ASP.MS Word.ASP.NET, MVC.NET.Кажется, мы можем достичь любого конца спектра, но в середине нет места для сладкого.

В конечном счете, пожалуй, самое большее, что мы можем надеяться сказать, это «хорошо, по крайней мере, все безумиеизолированные в представлении ".Я говорю «надежда», потому что по моему опыту гораздо проще сказать «объектно-ориентированный», чем делать объектно-ориентированный со всеми принципами программного обеспечения, которые подразумевает ОО.

В долгосрочной перспективе суп с тегами не проблема,Это абсолютно не проблема в контексте MVC.Ужасное кодирование - проблема.Части MVC, слитые вместе, как сиамские триплеты, ясно демонстрирующие некомпетентность в принципах разработки программного обеспечения и кодирования, являются гораздо большим преступлением.Парадигма MVC;это не заставит вас писать код быстрее.И это, конечно, не предотвратит кошмар обслуживания кода, если вы не знаете, какого черта вы делаете.

1 голос
/ 10 января 2012

Вы можете использовать GWT, ZK, Vaadin, JSF 2 или что-то, что скрывает HTML.Я не знаю, что вы подразумеваете под MVC.Шаблон Django / RoR / CakePHP Model-View-Presenter иногда называют MVC или настоящим MVC.Если вы придерживаетесь MVC, вы должны иметь ТОЛЬКО привязку данных и триггеры событий в вашем коде представления.

Я думаю, что это проблема дизайна, а не технологии.

1 голос
/ 08 января 2012

Не делайте никаких расчетов в коде вашего шаблона.

Посмотрите, что разрешено в Django: https://docs.djangoproject.com/en/1.3/topics/templates/

Без арифметики.Нет передачи параметров в методы.Нет определений любого вида (кроме как в циклах).Это заставляет вас делать почти все в методах представления и передавать любые требуемые объекты и списки, что обеспечивает его чистоту.

1 голос
/ 04 января 2012

Преимущество слоя представления по сравнению с супом тега состоит в том, что слой представления должен изолировать плохую логику от неверных данных, упрощая поиск причины. Это не произойдет автоматически, оно должно быть включено в ограничения кода представления. Лучший подход, который я видел в отношении HTML-представлений с использованием MVC, заключается в следующем (из Тони Марстон ):

  • Код, который преобразует данные в HTML, является логикой отображения.
  • Код, который создает или получает данные, которые впоследствии преобразуются в HTML, не является логикой отображения.

Знание - это пол дела, последовательная реализация - это другое. С большой властью сопряжена большая ответственность, поэтому использование ограниченного набора команд помогает реализовать более чистый код. Минимальные заявления будут напечатаны и включают. Циклы и привязка данных для создания таблиц, списков или форм могут обрабатываться библиотеками JavaScript или XSLT. Присвоение переменных, условная логика и манипуляции со строками могут выполняться в локальном или глобальном включении. Все остальное может обрабатываться моделью или контроллером.

1 голос
/ 03 января 2012
  1. Используйте Razr View Engine (мои предпочтения, я думаю, это выглядит аккуратнее).response.write "<table>" достаточно просто написать.Но вы делаете это в файле / классе, который ТОЛЬКО контролирует представление и может быть легко заменен или изменен, не затрагивая служебную логику?Это подводит меня к # 2.
  2. Обсудите разделение проблем с вашей группой и решите, где живет каждая часть логики.Где находятся точки соприкосновения зависимостей, сгруппирована ли вся ваша логика в DLL, которая не имеет представления о представлениях / контроллерах?Примите решение с самого начала и запишите его где-нибудь.
  3. Сохраняйте представления как представления!
  4. Ничего не делайте в представлении!
  5. Как только вы окажетесь на представлении, выпросто смотрят!
  6. Я уже говорил, что представления - это просто?

Я никого не жалею за использование MVP или любой другой парадигмы.Но если вы хотите попробовать MVC, сделайте это правильно, и вы обнаружите, что рефакторинг и обслуживание вашего кода будет намного проще.

my 2cents

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...