代码之家  ›  专栏  ›  技术社区  ›  Joshua Hayes

如何在ASP.NET MVC 3 RC中最好地实现保存并关闭取消表单操作

  •  12
  • Joshua Hayes  · 技术社区  · 14 年前

    我想知道在asp.netmvc3rc中提交表单时,如何实现多个表单操作。

    如果我正在编辑一个用户,例如,我想有一个带有以下按钮的操作栏;

    “保存”|“保存并关闭”|“取消”

    保存-提交表单并保存,返回到编辑屏幕。可作为标准输入/提交按钮轻松实现。这里没什么特别的。

    控制器代码可能看起来像

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

    取消-返回上一个屏幕。我在考虑用锚签来做这个。

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

    但我对如何实现 “保存并关闭” 当您需要提交相同的表单数据时。我想知道是否有一个可以为空的close参数?

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

    但是在这种情况下,我如何提交这个额外的参数和表单呢?

    如果可能的话,我希望有一个单一的表单操作来处理提交,如上面的模型。

    我也很感兴趣,如果有人已经提出了一个很好的用户交互模型围绕这个想法。

    解决方案

    我最终使用了下面的Omar建议,但我没有传入字符串,而是采用了枚举,这样我就不必在所有控制器中执行字符串检查。

    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> button,但希望使用枚举,我实现了一个用于执行解析的FormAction的自定义ModelBinder。

    我没有用 <button> 标记,因为主题已经为 <输入> 标签。

    2 回复  |  直到 14 年前
        1
  •  19
  •   Omar    14 年前

    一个表单中可以有多个相同的提交按钮 name 属性不同 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
        }
    }
    

    如果你不喜欢在 价值 属性,可以使用标准HTML <button> 用于定义单独值和单独文本的标记。

        2
  •  5
  •   anAgent Taky    13 年前

    @Omar的建议很棒。下面是我如何使它更通用一些,以防在提示用户删除对象时需要确认。 注意!在HttpPost中,我再次拉取对象,而不是使用传递给方法的项。您可以通过使视图包含所有属性来减少数据库调用,以便填充“Item”。

    这是视图模型

    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");
        }
    

    查看

        <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>