Используя ASP.NET MVC, как лучше всего избегать писать как "Добавить вид", так и "Редактировать представление"?

Вид "Добавить просмотр" и "Редактировать" часто невероятно схожи, так что необоснованно писать 2 представления. По мере того, как приложение развивается, вы вносили бы те же изменения в оба.

Однако обычно существуют тонкие различия. Например, поле может быть доступно только для чтения после его добавления, и если это поле является DropDownList, вам больше не нужен этот Список в ViewData.

Итак, должен ли я создать класс данных представления, который содержит всю информацию для обоих представлений, где, в зависимости от выполняемой операции, некоторые свойства будут пустыми?
Должен ли я включать операцию в данные представления как перечисление?
Должен ли я окружать все тонкие различия с помощью <% if (ViewData.Model.Op == Ops.Editing) {% > ?

Или есть лучший способ?

Ответ 1

Это довольно легко. Предположим, вы редактируете сообщение в блоге.

Здесь ваши 2 действия для нового /edit:

public class BlogController : Controller
{
   public ActionResult New()
   {
      var post = new Post();
      return View("Edit", post);
   }

   public ActionResult Edit(int id)
   {
      var post = _repository.Get(id);
      return View(post);
   }

   ....

}

И вот взгляд:

<% using(Html.Form("save")) { %>
<%= Html.Hidden("Id") %>

<label for="Title">Title</label>
<%= Html.TextBox("Title") %>

<label for="Body">Body</label>
<%= Html.TextArea("Body") %>

<%= Html.Submit("Submit") %>
<% } %>

И здесь действие "Сохранить", которое представляет представление:

public ActionResult Save(int id, string title, string body)
{
   var post = id == 0 ? new Post() : _repository.Get(id);
   post.Title = title;
   post.Body = body;

   _repository.Save(post);

   return RedirectToAction("list");
}

Ответ 2

Мне не нравятся представления, чтобы они стали слишком сложными, и до сих пор я имел тенденцию иметь отдельные представления для Edit и Add. Я использую пользовательский элемент управления для хранения общих элементов, чтобы избежать повторения. Оба представления будут сосредоточены вокруг одной и той же ViewData, и у меня есть маркер в моих данных, чтобы сказать, является ли объект новым или существующим объектом.

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

Мне нравится asp.net mvc, но он все еще созревает, и ему все еще нужно больше сахара, чтобы убрать некоторые трения о создании веб-сайтов.

Ответ 3

Я лично предпочитаю использовать if/else прямо в представлении. Это помогает мне сразу увидеть все происходящее.

Если вы хотите избежать суп-тега, я бы предложил создать вспомогательный метод.

<%= Helper.ProfessionField() %>

string ProfessionField()
{
    if(IsNewItem) { return /* some drop down code */ }
    else { return "<p>" + _profession+ "</p>"; }        
}

Ответ 4

Вы можете указать класс CustomViewData и передать здесь параметры.


public class MyViewData {
    public bool IsReadOnly { get; set; }
    public ModelObject MyObject { get; set; }
}

И оба представления должны реализовывать эту ViewData. В результате вы можете использовать предоставленное свойство IsReadOnly для управления результатом UserControl.

Как контроллер использует это, вы можете unit test его и ваши представления не имеют реализации, поэтому вы можете уважать принципы MVC.