【问题标题】:mvc4 ajax updating same pagemvc4 ajax 更新同一页面
【发布时间】:2012-09-19 17:01:28
【问题描述】:

我在页面上有一个用户列表,当我单击一个选项卡 (easytabs) 时,它们是在 ajax 事件期间加载的。然后,我将 ajax 加载到同一选项卡中的创建新用户部分视图。然后我使用此表单创建了一个新用户,但我不知道如何使用新的用户列表(包括新创建的用户)重新加载第一个部分视图。

HTML 以加载带有用户列表的标签面板:

<%= Ajax.ActionLink("Manage Users", "tabsUsers", null, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "ManageUsersPartial", InsertionMode = InsertionMode.Replace }, htmlAttributes: new { data_target = "#tabs-users" })%>

控制器:

[HttpGet]
public PartialViewResult tabsUsers()
{
    return PartialView("UsersPartial", userManager.GetUsers());
}

用户部分视图

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<LMS.Data.User>>" %>

<p>
    <%: Ajax.ActionLink("Create New", "Create", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "CreateUserPartial", InsertionMode = InsertionMode.Replace })%>
</p>
<table>
    <tr>
        <th>
            <%: Html.DisplayNameFor(model => model.UserName) %>
        </th>
        <th>
            <%: Html.DisplayNameFor(model => model.FirstName) %>
        </th>
        <th>
            <%: Html.DisplayNameFor(model => model.LastName) %>
        </th>
        <th>
            <%: Html.DisplayNameFor(model => model.Email) %>
        </th>
        <th>Actions</th>
    </tr>

<% foreach (var item in Model) { %>
    <tr>
        <td>
            <%: Html.DisplayFor(modelItem => item.UserName) %>
        </td>
        <td>
            <%: Html.DisplayFor(modelItem => item.FirstName) %>
        </td>
        <td>
            <%: Html.DisplayFor(modelItem => item.LastName) %>
        </td>
        <td>
            <%: Html.DisplayFor(modelItem => item.Email) %>
        </td>
        <td>
            <%: Html.ActionLink("Edit", "Edit", new { id = item.UserID })%> |
            <%: Html.ActionLink("Details", "Details", new { id=item.UserID }) %> |
            <%: Html.ActionLink("Delete", "Delete", new { id=item.UserID }) %>
        </td>
    </tr>
<% } %>

</table>

<br />

<div id="CreateUserPartial"></div>

这很好用,每次我点击标签时,数据都会按预期重新加载。

现在,

在 UsersPartial 视图中,我有另一个 Ajax Actionlink 将另一个部分视图加载到此部分视图中,以创建新用户:

来自用户部分视图的 HTML Ajax Actionlink:

<%: Ajax.ActionLink("Create New", "Create", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "CreateUserPartial", InsertionMode = InsertionMode.Replace })%>

这会在 UsersPartial 视图中加载以下 CreateUserView 视图

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<LMS.Data.User>" %>

<script src="<%: Url.Content("~/Scripts/jquery-1.6.2.min.js") %>"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>"></script>

<script type="text/javascript">
    $(function () {
        $('form').submit(function () {
            if ($(this).valid()) {
                $.ajax({
                    url: this.action,
                    type: this.method,
                    data: $(this).serialize(),
                    success: function (result) {
                        $('#result').html(result);
                    }
                });
            }
            return false;
        });
    });
</script>

<div id="result"></div>

<% using (Html.BeginForm())
   { %>
<%: Html.ValidationSummary(true, "Could not create new user.") %>
<fieldset>
    <legend>User</legend>
    <div class="editor-label">
        <%: Html.LabelFor(model => model.UserName) %>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(model => model.UserName) %>
        <%: Html.ValidationMessageFor(model => model.UserName) %>
    </div>
    <div class="editor-label">
        <%: Html.LabelFor(model => model.FirstName) %>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(model => model.FirstName) %>
        <%: Html.ValidationMessageFor(model => model.FirstName) %>
    </div>
    <div class="editor-label">
        <%: Html.LabelFor(model => model.LastName) %>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(model => model.LastName) %>
        <%: Html.ValidationMessageFor(model => model.LastName) %>
    </div>
    <div class="editor-label">
        <%: Html.LabelFor(model => model.Password) %>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(model => model.Password) %>
        <%: Html.ValidationMessageFor(model => model.Password) %>
    </div>
    <div class="editor-label">
        <%: Html.LabelFor(model => model.Email) %>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(model => model.Email) %>
        <%: Html.ValidationMessageFor(model => model.Email) %>
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>
<% } %>
<div>
    <%: Html.ActionLink("Back to List", "Index") %>
</div>

最后,在控制器中调用 CreateUser 的代码 CreateUserPartial 控制器代码:

[HttpPost]
    public ActionResult Create(AccountUser user)
    {
        if (ModelState.IsValid)
        {
            try
            {
                user.Password = user.Password.Encrypt();
                userManager.AddUser(user);
            }
            catch (DbEntityValidationException dbex)
            {
                foreach (var validationErrors in dbex.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        ModelState.AddModelError(validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
            }
            catch (DbUpdateException dbuex)
            {
                if (dbuex.InnerException != null)
                    if (dbuex.InnerException.InnerException != null)
                        if (dbuex.InnerException.InnerException.Message.Contains("Cannot insert duplicate key row in object"))
                            return Content("User already exists!", "text/html");
                else
                    ModelState.AddModelError("", "An unknown error occured when creating the user.");
            }
            catch (Exception)
            {
                ModelState.AddModelError("", "An unknown error occured when creating the user.");
            }
        }

        return Content("User created!", "text/html");
    }

这一切都有效...当创建用户时,它会显示用户已创建!正如预期的那样。

现在我的问题是,如何使用新用户重新加载 UsersPartial 视图中的列表?我无法弄清楚这部分。我感觉这与jQuery ajax成功方法有关,但我不知道如何重新加载用户列表,包括这个新创建的。

有什么想法吗?

谢谢!

【问题讨论】:

    标签: c# asp.net-mvc jquery


    【解决方案1】:

    请不要回发表单。而不是调用ajax调用

      <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<LMS.Data.User>" %>
    
    <script src="<%: Url.Content("~/Scripts/jquery-1.6.2.min.js") %>"></script>
    <script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>"></script>
    <script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>"></script>
    
    <% using (Html.BeginForm())
     <%: Ajax.BeginForm("Create",new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "ManageUsersPartial", InsertionMode = InsertionMode.Replace }, htmlAttributes: new { data_target = "#tabs-users" })
       { %>
    <%: Html.ValidationSummary(true, "Could not create new user.") %>
    <fieldset>
        <legend>User</legend>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.UserName) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.UserName) %>
            <%: Html.ValidationMessageFor(model => model.UserName) %>
        </div>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.FirstName) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.FirstName) %>
            <%: Html.ValidationMessageFor(model => model.FirstName) %>
        </div>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.LastName) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.LastName) %>
            <%: Html.ValidationMessageFor(model => model.LastName) %>
        </div>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.Password) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.Password) %>
            <%: Html.ValidationMessageFor(model => model.Password) %>
        </div>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.Email) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.Email) %>
            <%: Html.ValidationMessageFor(model => model.Email) %>
        </div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
    <% } %>
    <div>
        <%: Html.ActionLink("Back to List", "Index") %>
    </div>
    

    然后方法应该返回 paratail 视图而不是 Content Type

        public ActionResult Create(AccountUser user)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    user.Password = user.Password.Encrypt();
                    userManager.AddUser(user);
                }
                catch (DbEntityValidationException dbex)
                {
                    foreach (var validationErrors in dbex.EntityValidationErrors)
                    {
                        foreach (var validationError in validationErrors.ValidationErrors)
                        {
                            ModelState.AddModelError(validationError.PropertyName, validationError.ErrorMessage);
                        }
                    }
    return PartialView("CreateUserPartial", user);
                }
                catch (DbUpdateException dbuex)
                {
                    if (dbuex.InnerException != null)
                        if (dbuex.InnerException.InnerException != null)
                            if (dbuex.InnerException.InnerException.Message.Contains("Cannot insert duplicate key row in object"))
                                return Content("User already exists!", "text/html");
                    else
                        ModelState.AddModelError("", "An unknown error occured when creating the user.");
    return PartialView("CreateUserPartial", user);
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", "An unknown error occured when creating the user.");
    return PartialView("CreateUserPartial", user);
                }
    
    return PartialView("UsersPartial", userManager.GetUsers());
            }
    
            return PartialView("UsersPartial", userManager.GetUsers());
        }
    

    【讨论】:

    • 不幸的是,这不起作用...返回该视图将原始列表保留在顶部,然后显示添加用户的新列表...我需要删除原始列表
    • 嘿,你的问题..你说它应该在新用户创建时更新列表,这样它才能工作。它会用数据库更新记录。我需要删除原始列表是什么意思?请探讨您的问题。
    • 好吧,我终于想通了。您的解决方案是正确的,但是我的 html 中有错误。我用正确的局部视图更新了错误的 div。您的回答使我得到了正确的答案(对我来说),所以谢谢。
    【解决方案2】:

    您必须在创建后返回一个新列表。而不是:

    return Content("User created!", "text/html");
    

    你应该这样做:

    return PartialView("UsersPartial", userManager.GetUsers());
    

    编辑:您的部分想要IEnumerable 的用户。如果您需要留言,请通过ViewBag 发送。

    【讨论】:

    • 我试过了,它只是附加了整个视图,所以看起来它们是堆叠的。
    • 我试过了,它只是附加了整个视图,所以看起来它们是堆叠的,这是一个视图->部分->部分,我需要它来重新加载父部分视图.使用上面的代码,它只显示两个用户列表,一个未更新(原始),一个新更新。另外,如果成功,我希望它删除 CreateUserPartial
    猜你喜欢
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    相关资源
    最近更新 更多