2

我一直在寻找一种使用模式弹出窗口更新数据的方法。 现在我正在使用 devexpress,因为我们已经在使用其他 devexpress 控件(但如果 jquery 库更容易,这可能会改变!!)

坚持验证方面。坦率地说,对于我想要实现的目标,整个过程似乎相当困难。

无论如何,让我描述一下我目前制定的过程:

-索引页面包含可以更新的不同元素的概述。使用 HtmlExtension,我能够创建一个 devexpress 弹出窗口,它会在您打开弹出窗口时加载编辑页面。=> @Html.PopupControl().WithText("Edit").PopupGoesTo(Url.Action("EditPopup"等)

- 编辑页面 - 只是部分视图 - 工作得很好。我创建了一个小测试页面,其中包含 1 个文本框,它采用十进制。

我想使用 ajax 提交表单(因为坦率地说,如果我做一个完整的回帖,我不知道如何显示验证,因为我需要能够创建弹出窗口并将数据绑定到它并触发验证错误)。

  <script type="text/javascript">
    function EndPopUpUpdate(message) {
        if (message.url) {
            window.locatin.href = url;
        }
        $("#submitButtonPopUp, #loadingPopUp").toggle();
    }

    function BeginPopUpUpdate() {
        $("#submitButtonPopUp, #loadingPopUp").toggle();
    }
</script>

using (Ajax.BeginForm("Edit", "xxx", new AjaxOptions {  UpdateTargetId = "PopUpDiv", HttpMethod = "Post", OnBegin = "BeginPopUpUpdate", OnComplete = "EndPopUpUpdate"}, new { id = "PopUpForm" }))
    {
        <div id="PopUpDiv">
            @Html.Partial("EditPopup", new xxxViewModel())
        </div>
    }

当我通过手动重新挂钩 jquery 事件回发时,我能够实现验证(因为这些事件不会被挂钩,因为页面是动态加载的)

function ReconnectValidation() {
    $("#PopUpForm").ready(function () {
        $.validator.unobtrusive.parse("#PopUpForm");
    });

    $("#submitButton").click(function (e) {
        var form = $("#PopUpForm");
        if (!form.valid()) {
            e.preventDefault();
        }
    });
}

所以这处理了我的客户端验证,这很有效。

现在,我的实际问题!服务器端验证。

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([ModelBinder(typeof(CommandModelBinder))] UpdateCommand command)
    {
        if (!ModelState.IsValid)
        {
            //using the command pattern
            var handlerResult = HandlerLocator.GetQueryHandler<IGetOverviewHandler>().Execute(..);
            return PartialView("EditPopUp", handlerResult.ViewModel);
        }

        HandlerLocator.GetCommandHandler<UpdateCommand>().Handle(command);
        var returnLink = Url.Action("Index", new {..});
        return Json(new { url = returnLink }, JsonRequestBehavior.AllowGet);
    }

我编写了一个 CustomModelBinder,它只在我的命令对象(如果你愿意的话,我的返回模型)中查找属性,并在 formcollection 中查找是否可以找到具有相同名称的匹配对象。然后它会尝试转换它,如果失败,它会将 ModelError 绑定到我的 ModelState。

所以,现在我们有一个有效或无效的 ModelState。如果它有效,我想重定向到索引(这样我的概述可以更新)。我读过我应该在客户端处理这个问题,因为 ajax.BeginForm 将用结果替换“PopUpDiv”-div(它只是在我的页面中创建相同的页面)。

这是 onComplete 事件:

function EndPopUpUpdate(message) {
            if (message.url) {
                window.locatin.href = url;
            }
            $("#submitButtonPopUp, #loadingPopUp").toggle();
        }

问题是,我没有收到 json 消息,但收到了 PartialView。这意味着我无法访问 message.url..因为这不是我收到的:/

所以这是问题1

如果对象无效,我想返回带有模型的部分视图并向用户提供错误。当我返回部分视图时,它只是替换当前视图,但不显示任何验证错误..

那是第2个问题:)

此外,如果您知道解决此问题的更好方法,请不要犹豫做出回应(因为这种方法看起来确实令人费解-或应该做-)

很抱歉这篇冗长的帖子,但我希望一切都清楚。

感谢您的帮助和时间!

4

1 回答 1

4

我之前使用过 jQuery UI () 中的对话框插件,我发现它效果很好。我通常会在弹出窗口中的 iframe 中打开链接,这避免了您描述的问题,因为页面是动态加载的,因此 jQuery 验证事件没有连接 - 客户端和服务器端验证都应该正常工作,就在这个 iframe 中。

这种技术的好处是您可以在索引页面中正常生成操作链接,只需向它们添加一类弹出窗口,例如

@Html.ActionLink("Edit", "Edit", new { id = Model.Id }, new { @class = "popup" })

然后,您可以使用 jQuery 在 iframe 对话框中打开这些链接,例如:

$("a.popup").click(function(e) {
    e.preventDefault();
    $("<iframe />").attr("src", $(this).attr("href") + "?popup=true").dialog({ show: "fadeIn", modal: true, width: 300, height: 300});
});

这基本上会查找弹出链接,取消默认行为(页面导航)并在弹出窗口中的 iframe 中打开该 URL,添加查询字符串以识别页面在弹出窗口中。这个查询字符串的原因和知道它的弹出允许您在视图中加载不同的布局页面,可能通过操作过滤器,例如:

public class Popup : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Result != null
            && filterContext.Result is ViewResult
            && filterContext.RequestContext.HttpContext.Request["popup"] == "true")
            (filterContext.Result as ViewResult).MasterName = "~/Views/Shared/_PopupLayout.cshtml";
    }
}

这意味着您可以轻松地将此属性应用于您希望应用操作方法的类。此方法还意味着,如果您将来改变对实现的想法(即删除弹出窗口),那么您可以轻松删除取消点击的 jQuery,您的应用程序将继续作为具有单独页面的普通 MVC 应用程序运行,并且所有导航/验证等将“正常工作”。

我希望一切都有意义并有所帮助。

于 2012-08-06T16:46:47.320 回答