Как лучше всего реализовать Save | Сохранить и закрыть | Отмена действий формы в ASP.NET MVC 3 RC - PullRequest
13 голосов
/ 24 ноября 2010

Мне интересно, как вы можете реализовать несколько действий с формами при отправке формы в asp.net mvc 3 RC.

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

«Сохранить» |"Сохранить и закрыть" |«Отмена»

Сохранить - Отправка формы и сохранение, возвращение вас на экран редактирования.Может быть легко реализована в виде стандартной кнопки ввода / вывода.Здесь нет ничего особенного.

Код контроллера для этого может выглядеть как

public ActionResult Edit(UserViewModel model)
{
  ...
  return RedirectToAction("Edit", model.Id");
}

Отмена - просто возвращает вас к предыдущему экрану.Я думал об использовании тега привязки для этого.

<a href="@Request.UrlReferrer" class="button">Cancel</a>

Но я нахожусь в тупике от того, как реализовать "Сохранить и закрыть" , когда вам нужно отправить те же данные формы.Возможно, мне было интересно иметь закрываемый закрывающий параметр?

public ActionResult Edit(UserViewModel model, bool? close)
{
  ...
  return  close.GetValueOrDefault(false) ? RedirectToAction("Index", model.Id" : RedirectToAction("Edit", model.Id");
}

Но как мне передать этот дополнительный параметр вместе с формой в этом случае?

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

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

Solution

В итоге я воспользовался предложением Омара ниже, но вместо передачи строки я взял перечисление, поэтому мне не нужно проверять строки во всех моих контроллерах.

public ActionResult Edit(UserViewModel model, FormAction actionType)
{
  // pre-check
  if (actionType == FormAction.Cancel)
     // just return user to previous view and don't save.

  // Save code

  if (actionType == FormAction.Save)
     return ...
  else if (actionType == FormAction.SaveAndClose)
     ....
}

Поскольку я хотел более дружественный текст «Сохранить и закрыть» на кнопке <input>, но хотел использовать перечисление, я реализовал пользовательский ModelBinder для FormAction, который выполнял синтаксический анализ.

Я не использовалтег <button>, поскольку для тегов <input> уже была создана тема.

Ответы [ 2 ]

19 голосов
/ 24 ноября 2010

Вы можете использовать несколько кнопок отправки в форме с одним и тем же атрибутом name, но с разными атрибутами value. При нажатии на любую кнопку соответствующий value будет опубликован на сервере.

Вы можете использовать простую ссылку для Cancel, но я все равно включу ее в качестве кнопки.

<input type="submit" name="actionType" value="Save" />
<input type="submit" name="actionType" value="Save and Close" />
<input type="submit" name="actionType" value="Cancel" />

И в вашем действии проверьте значения.

public ActionResult Edit(string actionType)
{
    if(actionType == "Save")
    {
        // Save action
    }
    else if (actionType == "Save and Close")
    {
        // Save and quit action
    }
    else
    {
        // Cancel action
    }
}

Если вам не нравится иметь длинный текст в атрибуте value, вы можете использовать стандартный тег HTML <button>, который позволяет определять отдельное значение и отдельный текст.

5 голосов
/ 04 марта 2012

Предложение @Omar великолепно. Вот как я сделал это немного более общим в случае, когда я хотел получить подтверждение, когда пользователю предлагается удалить объект. Заметка! в HttpPost я снова вытягиваю объект, а не использую элемент, переданный методу. Вы можете уменьшить вызов БД, имея представление, содержащее все свойства, поэтому «Элемент» заполнен.

Вот модель просмотра

public class DeleteViewModel<T> {
    public string ActionType { get; set; }
    public T Item { get; set; }
}

Контроллер

    public ActionResult Delete(int id) {
        DeleteViewModel<Category> model = new DeleteViewModel<Category>() {
            Item = categoryRepository.Categories.FirstOrDefault(x => x.CategoryID == id)
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Delete(DeleteViewModel<Category> model) {
        if (model.ActionType == "Cancel")
            return RedirectToAction("Index");
        else if (model.ActionType == "Delete") {
            var cat = categoryRepository.Categories.FirstOrDefault(x => x.CategoryID == model.Item.CategoryID);
            categoryRepository.Delete(cat);
            return RedirectToAction("Index");
        }        
        //Unknown Action
        return RedirectToAction("Index");
    }

View

    <div class="actions">
        <div class="actions-left"><input type="submit" value="Cancel" name="ActionType"/></div>
        <div class="actions-right"><input type="submit" value="Delete" name="ActionType" /></div>
    </div>   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...