【问题标题】:How to handle PartialView with different model than parent View如何使用与父视图不同的模型处理 PartialView
【发布时间】:2012-09-06 06:19:09
【问题描述】:

我将 VS2012 RC 与 MVC4 结合使用,机器人用于所有意图和目的,让我们假设它是 MVC3。我想知道关于如何使用与父视图使用不同模型的表单来处理 PartialViews 的标准最佳实践是什么。

例如,这是一个显示所有可用角色的表格的视图,还有一个允许用户添加更多角色的表单。

主视图 - Roles.cshtml:

@model IEnumerable<RobotDog.Models.RoleModel>

<table>
    @foreach(var role in Model) {
        <tr>
            <td class="roleRow">@role.Role</td>
        </tr>
    }
</table>
<div class="modal hide">
    @Html.Partial("_AddRolePartial")
</div>

_AddRolePartial.cshtml

@model RobotDog.Models.RoleModel

@using(Html.BeginForm("AddRole","Admin", FormMethod.Post)) {
    @Html.TextBoxFor(x => x.Role, new { @class = "input-xlarge", @placeholder = "Role"})
    <input type="submit" value="Submit" class="btn btn-primary btn-large"/>
}

型号:

public class RoleModel {
    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "Role")]
    public string Role { get; set; }
}

视图控制器:

public ActionResult Roles() {
    var model = from r in System.Web.Security.Roles.GetAllRoles()
                select new RoleModel {Role = r};
    return View(model);
}

PartialView 的控制器:

[HttpPost]
public ActionResult AddRole(RoleModel model) {
    try {
        System.Web.Security.Roles.CreateRole(model.Role);
        RedirectToAction("Roles");
    } catch(Exception) {
        ModelState.AddModelError("", "Role creation unsuccessful.");
    }

    return ????; // not sure how to pass ModelState back to partialView
}

我曾想过创建一个包含 RoleModelIEnumerable&lt;RoleModel&gt; 的 ViewModel,但似乎有一种更流线型的方式来完成我想要的事情,而不必每次我想使用这个 PartialView 时都创建一个 ViewModel。

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 partial-views


    【解决方案1】:

    我想您是在问如何将 RoleModel 传递给 add RoleModel 模式弹出窗口。由于您正在创建一个新角色,我假设您需要一个空模型。你可以像下面这样传递它:

    <div class="modal hide">
        @Html.Partial("_AddRolePartial", new RoleModel())
    </div>
    

    或者只是使用控制器的支持 GET 方法执行 @Html.RenderAction("AddRole") 以支持填充项目。

    public ActionResult AddRole() {
        var model = new RoleModel();
        //populate with any items needed for the Add Role Model View
        return View(model);
    }
    

    【讨论】:

    • 是的,但这只是解决方案的一半。当我将表单提交到 AddRole 控制器时,如果发生异常,如何将ModelState 发送回表单?
    • 在这种情况下,您实际上只面临两个选择。您要么需要使用 AJAX 请求,它只会更新与添加角色相关联的页面部分,要么需要包含更新 ViewModel 以包含角色列表和空角色 ViewModel。我会推荐 AJAX,否则当您必须发回错误时,您将(可能)不得不一遍又一遍地重新查询您的角色。使用 AJAX,您可以轻松返回模型错误,甚至可以将新创建​​的角色附加到现有列表中。
    • 所以我的控制器会返回JsonResult,如果提交成功,我会在客户端处理重新加载页面?
    • 这可能是一种方法——当然。在我们的 MVC 项目中,我们有一个 AjaxResultViewModel,我们以 JSON 形式返回(它具有成功、消息、目标、内容等属性),我们可以使用通用 JQuery 处理程序解析以确定下一步要做什么。 if(!data.successful){showError(data.Message)} 例如
    • Tommy,您介意更新您的答案以反映 cmets。我只想让我的问题的答案显而易见,而不必滚动浏览所有 cmets。谢谢楼主:)
    【解决方案2】:

    我个人不喜欢在表单中使用局部视图,因为局部视图不能正确渲染子模型(即,它们没有考虑模型的层次结构)。

    这就是存在 Display 和 EditorTemplates 的原因。它们非常适合呈现特定的数据类型。

    但是,在您的情况下,由于您的视图没有自己的任何形式,并且最终结果只是父模型集合的单个项目,因此部分视图实际上是一种更好的方法,因为您可以向其传递与视图使用不同的模型。

    正如其他人所指出的,您可以轻松地将空模型作为第二个参数传递给部分。我不喜欢在视图中更新新对象,但看起来那里没有很多选择,因为替代方案会很混乱。

    【讨论】:

      【解决方案3】:

      如何将表单帖子更改为 ajax 表单帖子,目标更新部分 id 是 div,您将添加到父视图(有效地围绕 Roles.cshtml)。

      添加一个新动作public ActionResult _Roles(),它将return PartialView("Roles", model)

      接下来,在 Post Action 中,Return RedirectToAction(...Roles Partial Action ...) 位于末尾,并删除 try 中的 RedirectToAction("Roles")。

      【讨论】:

      • 这听起来像是一个有趣的解决方案。我不明白周围 div 的意义。你介意详细说明吗?也许是一些示例代码?
      • 您需要一个容器,以便将加载 _Roles 的 ajax 结果放入其中。我错误地建议容器位于 Roles.cshtml 中。容器应该在父视图中。我已经调整了我的答案。将尝试与您合作。
      猜你喜欢
      • 2015-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多