asp.net mvc Ajax.BeginForm克隆

时间:2011-01-17 02:00:20

标签: asp.net-mvc asp.net-mvc-2

我正在使用asp.net mvc ajax。

部分视图使用Ajax.BeginForm(只是一个例子):

<div id="divPlaceholder">
<% using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "divPlaceholder" })) { %>
     ... asp.net mvc controls and validation messages
     <input type="submit" value="Save" />
<% } %>
</div>

更新后,如果验证失败,则html为:

<div id="divPlaceholder">
    <div id="divPlaceholder">
    ...form
    </div>
</div>

我不喜欢插入返回的html,而是应该替换原来的div。

可能在POST时我不应该在局部视图中渲染<div>形式或渲染没有id的div。

在这种情况下我还能做些什么?

我在想,也许我应该编写一个帮助程序,比如Ajax.DivBeginForm,它将在GET中的div内部呈现表单并在POST上隐藏div。

有人可以提供一个很好的建议如何编写这样的帮助器(Ajax.DivBeginForm)吗?

我希望使用关键字:

<% using (Ajax.DivBeginForm(new AjaxOptions { UpdateTargetId = "myId" })) { ... }%>

3 个答案:

答案 0 :(得分:2)

我将在这里采用一种不同的方法,而不是让原始解决方案起作用,我建议使用此方案中通常遵循的模式而不使用帮助程序。我意识到这比原来的帖子晚一点,但是为了将来任何人使用:)

如果您的局部视图有一个表单,那么您将继续发布,并在表单中的表单中返回表单等,以便您希望让您的PARENT包含BeginForm,div和renderpartial

using (Ajax.BeginForm("Index", "ProjectManager", new AjaxOptions() ....
<div id="divPlaceholder">
     Html.RenderPartial(....)
</div>

如果您想将此逻辑封装在客户屏幕上显示的“订单”部分视图中,那么您有两个选项。 1.在父Customer视图中包含BeginForm(这会降低代码的可重用性,因为任何想要包含“Order”局部视图的视图都必须包含ajax连接。 要么 2.订单有两个部分视图。一个是OrderIndex.ascx(如果是razor则是cshtml),一个是OrderIndexDetail.ascx(或者你决定的任何命名约定)

OrderIndex包含您的Ajax.beginform和OrderIndexDetail没有表单,只有部分视图详细信息。

选项2是更多的代码(好吧,实际上大约30多秒的编码时间将ajax.beginform移动到另一个视图中)但增加了代码的可重用性。

答案 1 :(得分:1)

我的解决方案。如果出现问题,请评论。

public class DivMvcForm : MvcForm
{
    private bool _disposed;
    private MvcForm mvcForm;
    private ViewContext viewContext;

    public DivMvcForm(MvcForm mvcForm, ViewContext viewContext) : base(viewContext)
    {
        this.mvcForm = mvcForm;
        this.viewContext = viewContext;
    }

    protected override void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            _disposed = true;

            mvcForm.EndForm();

            viewContext.Writer.Write("</div>");
        }
    }
}

辅助

public static class AjaxHelperExtensions
{
    public static MvcForm DivBeginForm(this AjaxHelper ajaxHelper, AjaxOptions ajaxOptions)
    {
        var tagBuilder = new TagBuilder("div");

        if (ajaxHelper.ViewContext.HttpContext.Request.RequestType == "GET" 
            && string.IsNullOrWhiteSpace(ajaxOptions.UpdateTargetId) != true)
        {
            tagBuilder.MergeAttribute("id", ajaxOptions.UpdateTargetId);
        }

        ajaxHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));

        var theForm = ajaxHelper.BeginForm(ajaxOptions);

        return new DivMvcForm(theForm, ajaxHelper.ViewContext);
    }
}

它是如何运作的

<% using (Ajax.DivBeginForm(new AjaxOptions { UpdateTargetId = "divPlaceholder" })) { %>
    ... controls
<% } %>

结果 - 当ModelState无效时,局部视图返回没有id的div。

答案 2 :(得分:0)

您可以自己处理提交表单:

<div id="divPlaceholder">
<% using (Html.BeginForm("action", "controller", FormMethod.Post, new { id = "submitForm"})) { %>
     ... asp.net mvc controls and validation messages
     <input type="submit" value="Save" />
<% } %>
</div>

并写一些javascript为:

$('#submitForm').submit(function() {
   $.post('post-to-this-url', 
      data: { foo: formvalue1, bar: formvalue2},
      function(data) {
      // update html here
   }); 
   return false;
})