ASP.NET MVC 3 - Частковий шаблон проти шаблону та редактор


303

Отже, назва повинна говорити сама за себе.

Для створення повторно використовуваних компонентів у 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 -->

Отже, моє запитання - коли / як ви вирішите, який із трьох використовувати?

Що я дійсно шукаю - це перелік питань, які слід задати собі перед створенням, на які відповіді можна використовувати, щоб визначити, який шаблон використовувати.

Ось дві речі, які я вважаю кращими за допомогою EditorFor / DisplayFor:

  1. Вони поважають ієрархії моделей при наданні HTML-помічників (наприклад, якщо у вашої моделі "Foo" є об'єкт "Bar", HTML-елементи для "Bar" будуть надані з "Foo.Bar.ElementName", тоді як у часткової буде " ElementName ").

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

Я також чув, що DisplayFor надає шаблон "лише для читання", але я цього не розумію - не можу я перекинути туди форму?

Може хтось розповість мені інші причини? Чи є десь список / стаття, яка порівнює три?


Поняття, що стоять за шаблонами редактора та дисплея, чітко визначені в документації для asp.net mvc 2. Шаблони є частинами, які дотримуються певної конвенції. Ситуації, які роблять шаблони кращими чи гіршими, ніж старі партії, майже суворо залежать від того, чи варто конвенція дотримуватися вашої заяви.
Нік Ларсен

Відповіді:


301

EditorForvs DisplayForпросто. Семантика методів полягає у формуванні редагування / вставки та відображення / читання лише переглядів (відповідно). Використовувати DisplayForпід час відображення даних (тобто, коли ви генеруєте знаки і проміжки, що містять значення моделі). Використовуйте EditorForпід час редагування / вставки даних (тобто, коли ви генеруєте вхідні теги всередині форми).

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

З іншого боку Partial, орієнтоване на огляд в тому, що ви в основному переймаєтесь вибором правильного часткового зору. Вид не обов'язково потребує моделі, щоб правильно функціонувати. Він може просто мати загальний набір розмітки, який буде повторно використаний на всьому сайті. Звичайно, часто ви хочете вплинути на поведінку цього часткового, і в цьому випадку ви можете перейти у відповідну модель перегляду.

Ви не запитували про те, @Html.Actionщо також заслуговує на згадку тут. Ви можете подумати про це як про більш потужну версію, Partialоскільки вона виконує дію з контролером, а потім надає перегляд (який, як правило, частковий вигляд). Це важливо, оскільки дочірні дії можуть виконувати додаткову ділову логіку, яка не належить до часткового перегляду. Наприклад, він може представляти собою компонент кошика для покупок. Причина його використання полягає в тому, щоб уникнути виконання роботи, пов’язаної з кошиком, у кожному контролері вашої програми.

Зрештою, вибір залежить від того, що ви моделюєте у своїй програмі. Також пам’ятайте, що ви можете змішувати та поєднувати. Наприклад, у вас може бути частковий вигляд, який викликає EditorForпомічника. Це дійсно залежить від вашої програми та як визначити її, щоб заохотити максимальне використання коду, уникаючи повторення.


4
Це чудова відповідь, саме те, що я шукав. Насправді я базувався на тому, щоб ти прийшов і відповів на це. :) Дякую Марчін.
RPM1984

Як ви використовуєте примітки для визначення шаблону відображення та шаблона редактора для однієї властивості?
stormwild

3
@stormwild або використовуйте умовні позначення та називайте свої шаблони за моделлю, до якої вони відносяться (/Views/DisplayTemplates/MyModel.cshtml), або явно змушуйте її / анотацію UIHint.
Том Уейсон

Будь-яка порада, яку вибрати для створення багаторазового майстра "зареєструвати користувача"? Я хочу створити ці представлення (і контролери) в окремій збірці, якщо це можливо. Ака, спосіб перерозподілити серед декількох команд ці доступні форми / контролери mvc. (ми створили єдиний спосіб керування користувачами / зберігання (сервіси webapi) ... але кожна команда створює власні сторінки mvc: <Спасибі.
granadaCoder

Де ви зберігаєте ці шаблони? Чи потрібно мені зберігати їх у Shared / EditorTemplates чи можливо зберігати їх безпосередньо в папці поточного контролера (коли мені вони потрібні лише там)?
Сантос

15

Ви, звичайно, можете налаштувати DisplayForвідображення форми, яку можна редагувати. Але конвенція DisplayForповинна бути readonlyі EditorForбути для редагування. Дотримання конвенції забезпечить, що незалежно від того, в що ви потрапляєте DisplayFor, він буде робити те ж саме.


2
Я не думаю, що насправді виникає питання / сумніви щодо того, коли слід використовувати шаблони відображення проти шаблонів редактора. Справжнє питання полягає в тому, коли слід використовувати шаблони проти партії. Ваша відповідь це цілком пропускає.
Джошуа Хейс

19
@Joshua - я думаю, що до цього було питання: "Я також чув, що DisplayFor надає шаблон" лише для читання ", але я цього не розумію - не можу я перекинути туди форму?"
Роберт Леві

13

Тільки для того, щоб оцінити мій 2с, наш проект використовує часткове подання з кількома вкладками jQuery, а кожна вкладка відображає свої поля з власним частковим поданням. Це спрацювало чудово, поки ми не додали функцію, згідно з якою деякі вкладки ділилися загальними полями. Наш перший підхід до цього полягав у створенні ще одного часткового подання з цими загальними полями, але це стало дуже незграбним при використанні EditorFor та DropDownListFor для візуалізації полів та випадання спадів. Щоб отримати ідентифікатори та імена унікальними, нам довелося візуалізувати поля з префіксом залежно від батьківського часткового перегляду, який його рендерував:

    <div id="div-@(idPrefix)2" class="toHide-@(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: viewState.@(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>

Це стало досить потворно, тому ми вирішили використати редакторські шаблони замість цього, які вийшли набагато чистішими. Ми додали нову модель перегляду із загальними полями, додали відповідний шаблон редактора та вивели поля, використовуючи шаблон редактора з різних батьківських представлень. Шаблон редактора правильно відображає ідентифікатори та імена.

Отже, коротше кажучи, переконливою причиною використання шаблонів редактора стала необхідність відображення деяких загальних полів на декількох вкладках. Часткові перегляди не розроблені для цього, але шаблони редактора прекрасно справляються зі сценарієм.


1
У мене була аналогічна проблема з використанням вкладок і в кінцевому підсумку з допомогою BeginCollectionItem Стів Сандерсон, який генерує унікальний ідентифікатор елемента управління для вас: blog.stevensanderson.com/2010/01/28 / ...
Wilky

1

Використовуйте _partialпідхід перегляду, якщо:

  1. Перегляд центральної логіки
  2. Що зберігати всі _partialHTML, пов’язані з переглядом, лише в цьому режимі перегляду. У способі шаблону вам доведеться зберегти HTML за межами виду шаблону, наприклад "Головний заголовок або будь-яка зовнішня межа / налаштування".
  3. Хочете надати частковий вигляд за допомогою логіки (Від контролера) за допомогою URL.Action("action","controller").

Причини використання шаблону:

  1. Хочете видалити ForEach(Iterator). Шаблон достатньо, щоб ідентифікувати модель як тип списку. Це зробить автоматично.
  2. Модель центральної логіки. Якщо в одній дисплеї для папки Шаблон знайдено кілька представлень, то візуалізація залежатиме від пройденої моделі.

1

Ще одна відмінність, про яку досі не згадувалося, полягає в тому, що в частковому перегляді не додаються префікси моделі, тоді як шаблон є. Ось проблема

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.