为什么Ajax在第一次请求时正常工作,但在第二次请求时返回新页面上的部分视图?

时间:2014-09-14 20:47:32

标签: jquery ajax asp.net-mvc-5

我在表格的每一行中嵌套了一个Ajax表单,以提供添加/删除功能。部分列出了所有可用角色(Microsoft身份2.0),并为每个角色列出了指定用户是否与该角色相关联,以及用于切换用户进出角色的按钮(Ajax)。

当我使用Ajax.Beginform时,一切正常,但是当我使用常规jquery时,它会在我第一次单击按钮切换用户与角色的关联时起作用,但第二次在新的上加载局部视图时页面本身没有CSS样式。

在stackoverflow上搜索,我看到其他人有类似的问题,但他们似乎根本没有ajax工作,不像我有第一个请求工作,然后没有。我还应该提一下,我是Asp.net的新手,这是我第一次直接使用jquery(遵循Scott Allan关于PluralSight的教程)。

这是我已经尝试过的: 检查具有调试断点的ajax请求是否正在触发该操作。 检查我在布局视图中引用了jquery,并且不超过一次。 检查我是否以正确的顺序引用jquery和jquery unobtrusive ajax。 检查web.config是否将相关标志设置为true。

我已经被困在这几个小时了,任何指导都会非常感激。

BundleConfig.cs:

    namespace GCCP
{
    public class BundleConfig
    {
        // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
        public static void RegisterBundles(BundleCollection bundles)
        {   
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.validate*",
                        "~/Scripts/jquery.unobtrusive*"));

            bundles.Add(new ScriptBundle("~/bundles/gccp").Include(
                        "~/Scripts/gccp.js"));

            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));

            bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                      "~/Scripts/bootstrap.js",
                      "~/Scripts/respond.js"));

            bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css"));

            // Set EnableOptimizations to false for debugging. For more information,
            // visit http://go.microsoft.com/fwlink/?LinkId=301862
            BundleTable.EnableOptimizations = true;
        }
    }
}

行动方法:

public ActionResult UserRoles(string returnUrl, string UserName)
{
    ViewBag.ReturnUrl = returnUrl;

    UserRolesViewModel Model = new UserRolesViewModel();
    Model.UserName = UserName;
    Model.RoleAssignments = UserRoleAssignments(UserName);

    return View(Model);
}

[HttpPost]
public ActionResult ToggleUserToRoleAssignment(string returnUrl, string UserName, string RoleName)
{
    ViewBag.ReturnUrl = returnUrl;

    var userStore = new UserStore<ApplicationUser>(context);
    var userManager = new UserManager<ApplicationUser>(userStore);
    var roleStore = new RoleStore<IdentityRole>(context);
    var roleManager = new RoleManager<IdentityRole>(roleStore);
    string userID = userManager.FindByName(UserName).Id;

    if ( roleManager.RoleExists(RoleName) == true )
    {
        if ( userManager.IsInRole(userID, RoleName) == true )
        {
            userManager.RemoveFromRole(userID, RoleName);
        }
        else
        {
            userManager.AddToRole(userID, RoleName);
        }
    }

视图模型:

namespace GCCP.Models
{
    public class UserRolesViewModel
    {
        [Required]
        [Display(Name = "User")]
        public string UserName { get; set; }
        public Dictionary<string, bool> RoleAssignments { get; set; }
        public string AjaxTest { get; set; }
    }

}

查看:

@using GCCP.Models;
@using System.Web.Mvc.Ajax;
@model UserRolesViewModel

@{
    ViewBag.Title = "User Roles";
}

<h2>
    @Model.UserName  |  Assigned Roles 
</h2>

    @Html.Partial("_UserRolesList", Model)

部分视图:

@using GCCP.Models;
@using System.Web.Mvc.Ajax;
@model UserRolesViewModel

<div id="roleAssignmentList">
    <table class="table table-condensed">
        <thead>
            <tr>
                <th>
                    Roles
                </th>
                <th>
                    Assigned
                </th>
                <th>
                    Add / Remove
                </th>
            </tr>
        </thead>
        <tbody>
            @foreach ( var item in Model.RoleAssignments )
            {
                if ( item.Value )
                {
                    <tr class="active">
                        <td>
                            @item.Key
                        </td>
                        <td>
                            <i class="glyphicon glyphicon-ok"></i>
                        </td>
                        <td>
                            <form action="@Url.Action("ToggleUserToRoleAssignment")" method="post" data-gccp-ajax="true" data-gccp-target="#roleAssignmentList">
                                <input type="hidden" name="RoleName" value="@item.Key"/>
                                <input type="hidden" name="UserName" value="@Model.UserName"/>
                                <input type="submit" value="Change"/>
                            </form>
                        </td>
                    </tr>
                }
                else
                {
                    <tr>
                        <td>
                            @item.Key
                        </td>
                        <td>
                            <i class="glyphicon glyphicon-remove"></i>
                        </td>
                        <td>
                            <form action="@Url.Action("ToggleUserToRoleAssignment")" method="post" data-gccp-ajax="true" data-gccp-target="#roleAssignmentList">
                                <input type="hidden" name="RoleName" value="@item.Key"/>
                                <input type="hidden" name="UserName" value="@Model.UserName"/>
                                <input type="submit" value="Change"/>
                            </form>
                        </td>
                    </tr>
                }
            }
        </tbody>
    </table>
</div>

Jquery的:

$(function () {
    var ajaxFormSubmit = function () {
        var $form = $(this);

        var options = {
            url: $form.attr("action"),
            type: $form.attr("method"),
            data: $form.serialize()
        };

        $.ajax(options).done(function (data) {
            var $target = $($form.attr("data-gccp-target"));
            $target.replaceWith(data);
        });

        return false;
    };

    $("form[data-gccp-ajax='true']").submit(ajaxFormSubmit);

});

提前致谢:)

1 个答案:

答案 0 :(得分:2)

&#34;仅限第一次工作&#34;行为是典型的动态添加内容的情况,但事件直接绑定到元素(例如,在DOM就绪)。

相关部分将是:

$("form[data-gccp-ajax='true']").submit(ajaxFormSubmit);

仅在运行该行代码时绑定到现有表单。

另一种方法是使用委托的事件处理程序,附加到元素的不变的祖先:

e.g。

$('#roleAssignmentList').on("submit", "form[data-gccp-ajax='true']", ajaxFormSubmit);

通过监听提交事件来冒泡到该祖先,然后将jquery选择器应用于bubble-chain中的元素,然后应用该功能

如果您没有方便的不变的祖先,请使用document。我并非100%确定您没有完全替换#roleAssignmentList(或仅仅是其子代),因此该示例无法使用document代替。

e.g。

$(document).on("submit", "form[data-gccp-ajax='true']", ajaxFormSubmit);

但从不使用&#39; body&#39;作为委托事件处理程序目标(它有一些与样式相关的错误,这意味着它可能会错过某些事件)。