【问题标题】:ASP.NET MVC3 ajax partial view refreshASP.NET MVC3 ajax 局部视图刷新
【发布时间】:2012-05-12 14:24:10
【问题描述】:

我在 asp.net mvc3 中遇到 ajax 更新 div 的问题。

我有一个包含内容的视图

<div id="post_comments">
   @{Html.RenderPartial("_RefreshComments", Model);}
 </div>
<div id="commentForm">
@using (Ajax.BeginForm("Details", new { id = Model.Post.PostId }, new AjaxOptions
           {
              HttpMethod = "POST",
              InsertionMode = InsertionMode.InsertAfter, 
              UpdateTargetId = "post_comments"
            }
          ))
{
// form content goes here
<p id="buttons">
    <input type="submit" value="@Strings.Save" />
</p>
}

这是我的部分观点

@model Project.Models.Posts.PostDetailsViewModel   

@{ 
    foreach (var c in Model.ApprovedComments)
    { 
        @Html.DisplayFor(x => c)        
    } 
}

我有一个控制器

public ActionResult Details(int id, FormCollection form )
{
    var model = new PostDetailsViewModel(UnitOfWork, id);
    return PartialView("_RefreshComments", model);

}

我的布局cshtml中包含以下脚本

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

还有

  <appSettings>
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>  

确实有效,我可以添加 cmets,但控制器只返回 PartialView,不包含在布局中。我找到了ASP.net MVC3 - Razor Views and PartialViews with Ajax Postbacks,但从那里没有任何帮助。

有人有什么想法吗?

【问题讨论】:

  • 您能在浏览器的 javascript 调试工具中看到 AJAX 请求被触发吗?会不会有一些 javascript 错误?您是否确保jquery.unobtrusive-ajax.min.js 脚​​本存在于指定位置。你也引用了jquery 吗?
  • 不,Request.IsAjaxRequest() 总是返回 false。是的,我确信所有页面上都启用了该脚本。是的 jquery 可以工作,但我不知道为什么它返回 false。我已经阅读了一些关于这个的主题......但是......

标签: ajax asp.net-mvc-3 partial-views


【解决方案1】:

我会使用 jquery ajax 来调用操作,然后从控制器返回部分视图。然后使用 jquery 将返回的 html 重新加载到容器中。

首先,添加一个刷新按钮或可以触发 ajax 事件的东西...然后执行以下 javascript。

做这样的事情:

<div id="post_comments">     
  @{Html.RenderPartial("_RefreshComments", Model);}    
</div>
<div id="commentForm">
  @using (Ajax.BeginForm("Details", new { id = Model.Post.PostId }, new AjaxOptions    
  {
     HttpMethod = "POST",
     InsertionMode = InsertionMode.InsertAfter, 
     UpdateTargetId = "post_comments"
  }
))
{
// form content goes here
<p id="buttons">
  <input type="submit" value="@Strings.Save" />
  <input type="button" id="refreshButton" value="Refresh" />"
</p>
}





$('#refreshButton').click(function(){
   $.ajax({
      url: 'controller/Details.aspx',
      datatype: 'html',
      success: function(data) {
         $('#post_comments').empty().html(data);
      }
   }); 
});

显然,url 需要成为您操作的路径。除此之外,这对你来说应该很好。

【讨论】:

  • 它几乎可以工作,但我在通过@Url.Action() 传递参数时遇到了一些问题。我需要传递 formcollection 和 Id。
【解决方案2】:

用法:

    function onUploadComplete()
    {
        @Ajax.Update("targetId", helper => helper.Action("ActionName"))
    }

还有代码:

    /// <summary>
    /// I'd rather stab myself in the eye with a fork than bothering with php ever again and living without extension methods
    /// </summary>
    /// <param name="helper">makes sense to make it available here. who likes dozens of new helper classes</param>
    /// <param name="updateTargetId">simple enough</param>
    /// <param name="actionUrlFactory">resharper will show if we're messing stuff up. hurray.</param>
    /// <param name="isAsync">speaks for itself</param>
    /// <param name="options">might as well reuse that one for callbacks</param>
    /// <returns>generated code with compile time checks</returns>
    public static IHtmlString Update(this AjaxHelper helper, string updateTargetId, Func<UrlHelper, string> actionUrlFactory, bool isAsync = true, AjaxOptions options = null)
    {
        var requestUrl = actionUrlFactory(new UrlHelper(helper.ViewContext.RequestContext));
        if (options == null)
        {
            options = new AjaxOptions()
            {
                AllowCache = false,
                HttpMethod = "GET"
            };
        }

        string cache = options.AllowCache ? "true" : "false";
        string success = options.OnSuccess.Length > 0 ? ".done(" + options.OnSuccess + ")" : "";
        string fail = options.OnFailure.Length > 0 ? ".fail(" + options.OnFailure + ")" : "";
        string always = options.OnComplete.Length > 0 ? ".always(" + options.OnComplete + ")" : "";
        string isAsyncString = isAsync ? "true" : "false";

        // of course you can go way further here, but this is good enough for me. just sharing since i didn't find a nice solution here that doesnt involve writing js manually every time.
        string js = string.Format(@"
            $.ajax({{
                cache : {7},
                async : {6},
                url : '{0}',
                type : '{1}'
            }})
            .done(function(data){{
                $('#{5}').html(data);
            }});
            {2}
            {3}
            {4}
        ", requestUrl, options.HttpMethod, success, fail, always, updateTargetId, isAsyncString, cache);

        return new HtmlString(js);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    • 2021-07-17
    • 2011-08-10
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    相关资源
    最近更新 更多