ASP.NET MVC 3 - Partial vs Display Template vs Editor Template

Итак, название должно говорить само за себя.

Чтобы создать повторно используемые компоненты в ASP.NET MVC, у нас есть 3 варианта (могут быть другие, о которых я не упоминал):

Частичный вид:

@Html.Partial(Model.Foo, "SomePartial")

Шаблон пользовательского редактора:

@Html.EditorFor(model => model.Foo)

Пользовательский шаблон отображения:

@Html.DisplayFor(model => model.Foo)

В терминах фактического представления /HTML все три реализации идентичны:

@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->

Итак, мой вопрос: когда/как вы решаете, какой из трех использовать?

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

Вот две вещи, которые я нашел лучше с помощью редактора ForFor/DisplayFor:

  • Они уважают иерархии моделей при рендеринге HTML-помощников (например, если у вас есть объект "Bar" на вашей модели "Foo", элементы HTML для "Bar" будут отображаться с помощью "Foo.Bar.ElementName", в то время как частичное будет иметь "ElementName" ).

  • Более надежный, например, если у вас есть List<T> чего-то в вашей ViewModel, вы можете использовать @Html.DisplayFor(model => model.CollectionOfFoo), а MVC достаточно умен, чтобы увидеть его в коллекции и отобразить одиночный дисплей для каждого элемента ( в отличие от Partial, для которого требуется явный цикл цикла).

Я также слышал, что DisplayFor отображает шаблон "только для чтения", но я этого не понимаю - не мог ли я нарисовать форму там?

Может ли кто-нибудь сказать мне другие причины? Есть ли список/статья где-то, сравнивая три?

Ответ 1

EditorFor vs DisplayFor прост. Семантика методов заключается в создании разрешений редактирования/вставки и отображения/чтения (соответственно). Используйте DisplayFor при отображении данных (т.е. При создании div и интервалов, содержащих значения модели). Используйте EditorFor при редактировании/вставке данных (т.е. При создании тегов ввода внутри формы).

Вышеуказанные методы являются ориентированными на модель. Это означает, что они будут учитывать модельные метаданные (например, вы могли бы аннотировать ваш класс модели с помощью [UIHintAttribute] или [DisplayAttribute], и это повлияет на выбор шаблона для создания пользовательского интерфейса для модели. Они также обычно используются для модели данных (например, модели, представляющие строки в базе данных и т.д.)

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

Вы не спрашивали о @Html.Action, который также заслуживает упоминания здесь. Вы можете подумать об этом как о более мощной версии Partial в том, что она выполняет дочернее действие контроллера, а затем отображает представление (обычно это частичное представление). Это важно, потому что дочернее действие может выполнять дополнительную бизнес-логику, которая не принадлежит частичным представлениям. Например, он может представлять собой компонент корзины покупок. Причина его использования заключается в том, чтобы избежать выполнения работы с корзиной в каждом контроллере в вашем приложении.

В конечном счете выбор зависит от того, что вы моделируете в своем приложении. Также помните, что вы можете смешивать и сопоставлять. Например, у вас может быть частичное представление, которое вызывает помощник EditorFor. Это действительно зависит от того, что ваше приложение и как его использовать, чтобы поощрять максимальное повторное использование кода, избегая повторения.

Ответ 2

Вы, конечно, можете настроить DisplayFor для отображения редактируемой формы. Но соглашение для DisplayFor должно быть readonly и EditorFor для редактирования. Придерживание соглашения гарантирует, что независимо от того, что вы перейдете в DisplayFor, он будет делать то же самое.

Ответ 3

Просто, чтобы дать мой 2c, наш проект использует частичный вид с несколькими вкладками jQuery, и каждая вкладка отображает свои поля с собственным частичным представлением. Это работало нормально, пока мы не добавили функцию, при которой некоторые вкладки разделили некоторые общие поля. Наш первый подход к этому заключался в создании еще одного частичного представления с этими общими полями, но это очень неудобно при использовании EditorFor и DropDownListFor для рендеринга полей и выпадающих списков. Чтобы получить уникальные идентификаторы и имена, нам пришлось отображать поля с префиксом в зависимости от родительского частичного представления, которое его отображало:

    <div id="[email protected](idPrefix)2" class="[email protected](idPrefix)" style="display:none">
    <fieldset>
        <label for="@(idPrefix).Frequency">Frequency<span style="color: #660000;"> *</span></label>

        <input name="@(idPrefix).Frequency"
               id="@(idPrefix)_Frequency"
               style="width: 50%;"
               type="text"
               value="@(defaultTimePoint.Frequency)"
               data-bind="value: [email protected](viewStatePrefix).RecurringTimepoints.Frequency"
               data-val="true"
               data-val-required="The Frequency field is required."
               data-val-number="The field Frequency must be a number."
               data-val-range-min="1"
               data-val-range-max="24"
               data-val-range="The field Frequency must be between 1 and 24."
               data-val-ignore="true"/>

        @Html.ValidationMessage(idPrefix + ".Frequency")

        ... etc

    </fieldset>
</div>

Это получилось довольно уродливым, поэтому мы решили использовать Editor Templates вместо этого, который работал намного чище. Мы добавили новую модель View с общими полями, добавили соответствующий шаблон редактора и отобразили поля с использованием шаблона редактора из разных родительских представлений. Шаблон редактора правильно отображает идентификаторы и имена.

Короче говоря, веской причиной для использования шаблонов редакторов является необходимость создания некоторых общих полей на нескольких вкладках. Частичные представления не предназначены для этого, но Шаблоны Редакторов отлично справляются с этим сценарием.

Ответ 4

Используйте подход _partial view, если:

  • View Centric Logic
  • Что нужно, чтобы все _partial отображали связанные HTML только в этом представлении. В методе шаблона вам нужно будет оставить некоторый HTML вне шаблона, например "Основной заголовок" или любая внешняя граница/параметры.
  • Хотите сделать частичное представление логическим (от контроллера) с помощью URL.Action("action","controller").

Причины использования шаблона:

  • Хотите удалить ForEach(Iterator). Шаблон достаточно хорош, чтобы идентифицировать модель как тип списка. Он будет делать это автоматически.
  • Модельная логика. Если в одном и том же экране для шаблона найдено несколько видов, то рендеринг будет зависеть от пройденной модели.

Ответ 5

Еще одно отличие, которое не упоминалось до сих пор, заключается в том, что частичное представление не добавляет префиксы модели, пока шаблон Здесь является проблема