【问题标题】:Ajax.Beginform works only onceAjax.Beginform 只工作一次
【发布时间】:2015-09-18 17:12:46
【问题描述】:

我在尝试进行内联编辑时对笔记进行了部分查看,保存按钮仅能正常工作一次,但在第一次提交后停止工作。 这是我的视图代码:

<h4>Notes</h4>
<table class="table">
    @foreach (var note in Model)
    {
        <tr>
            <td style="width:150px;">@Html.DisplayFor(modelItem => note.CreatedOn)</td>
            @if (ViewData["ShowNoteType"] == null || ((bool)ViewData["ShowNoteType"] == true)) 
            { 
                <td style="width:120px;">@Html.DisplayFor(modelItem => note.NoteType)</td>
            }

            <td class="readOnlyProperty" data-note-id=@note.NoteID>@Html.DisplayFor(modelItem => note.LoggedBy)</td>
            <td class="readOnlyProperty" data-note-id= @note.NoteID>@Html.DisplayFor(modelItem => note.Text)</td>

                @using (Ajax.BeginForm("Edit", new { id = note.NoteID }, new AjaxOptions { HttpMethod = "POST", Url = "/Notes/Edit", UpdateTargetId = "noteslist", OnComplete = "OnNotesListReloaded" }, new { @role = "form", @class = "form-inline" }))
                {
                    @Html.AntiForgeryToken()
                    <td class="editableProperty" style="display:none;" data-note-id=@note.NoteID>
                        <div class="form-group">
                            @Html.EnumDropDownListFor(modelItem => note.LoggedBy, htmlAttributes: new { @class = "form-control" })
                        </div>
                     </td>
                    <td class="editableProperty" style="display:none;" data-note-id=@note.NoteID>
                        <div class="form-group">
                            @Html.EditorFor(modelItem => note.Text, new { htmlAttributes = new { @class = "form-control" } })
                        </div>
                     </td>

                        @Html.HiddenFor(modelItem => note.NoteID)
                        @Html.HiddenFor(modelItem => note.CandidateID)
                        @Html.HiddenFor(modelItem => note.JobID)
                        @Html.HiddenFor(modelItem => note.ContactID)
                    <td class="editableProperty" style="display:none;" data-note-id=@note.NoteID>
                        <button type="submit" class="btn btn-default btn-sm save-note" title="Save">
                            <span class="glyphicon glyphicon-save" aria-hidden="true" />
                        </button>
                    </td>
                }


            <td><a class="btn btn-default edit-note" data-note-id=@note.NoteID ><span class="glyphicon glyphicon-edit" aria-hidden="true" /></a></td>
            <td class="deletebutton" data-note-id=@note.NoteID>
                @using (Ajax.BeginForm("Delete", new { id = note.NoteID }, new AjaxOptions { HttpMethod = "POST", Url = "/Notes/Delete", UpdateTargetId = "noteslist", OnComplete = "OnNotesListReloaded" }, new { @role = "form", @class = "form-inline" }))
                {
                    @Html.AntiForgeryToken()

                    <input type="hidden" name="id" value="@note.NoteID" />
                    <input type="hidden" name="CandidateID" value="@ViewData["CandidateID"]" />
                    <input type="hidden" name="JobID" value="@ViewData["JobID"]" />
                    <input type="hidden" name="ContactID" value="@ViewData["ContactID"]" />

                    <button type="submit" class="btn btn-default btn-sm" title="Delete Note">
                        <span class="glyphicon glyphicon-trash" aria-hidden="true" />
                    </button>
                }
            </td>
        </tr>
    }
</table>

    @section Scripts {

    @Scripts.Render("~/bundles/custom")
}

保存按钮只能完美运行一次。 我必须将下拉列表和编辑器放在单独的 &lt;td&gt; 中,而不是将整个 Ajax 表单放在 &lt;td&gt; 中,以便它们在编辑时对齐。当我将整个 Ajax.Beginform 放在 &lt;td&gt; 中时,它工作得很好,但是它根本没有对齐。 所以任何人都可以帮助我使保存按钮工作并且字段正确对齐

这是我的 jquery 代码:

var OnNotesListReloaded = function () {

    $(".edit-note").click(function (event) {

        var elem = $(this).attr("data-note-id");
        $(".edit-note[data-note-id=" + elem + "]").hide();
        $(".readOnlyProperty[data-note-id=" + elem + "]").hide();
        $(".editableProperty[data-note-id=" + elem + "]").show();
        $(".deletebutton[data-note-id=" + elem + "]").hide();

    });
}

$(document).ready(function () {

    OnNotesListReloaded();

});

【问题讨论】:

  • 嗨。如果您的 ajax 调用是 post 类型,为什么要在 ajax.BeginForm 的第二个参数中传递 noteid ?
  • 嗨,请在 JS 中使用 preventDefault 方法,它会破坏服务器 HIT
  • @Vijay 我试过了: var flag = event.isDefaultPrevented();警报(标志);它返回错误。
  • 这些都不可能正常工作。您使用的 foreach 循环会生成大量无效的 html(重复的 id 属性),并且您的表单控件具有与您的模型完全没有关系的 name 属性。

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


【解决方案1】:

您可以使用其他方法来执行此操作。 让我们从 UI 开始到行动。
第 1 步: 仅在“For Loop”之外创建一个表单并将操作设置为 “/Notes/EditDelete”,别担心我们会在下一步创建一个动作。
第 2 步: 现在使用按钮在名称中使用类似这样的操作,您还可以传递 id 以及正在编辑或删除的记录。

<input type="submit" value="Edit" name="action:Edit" class="btn btn-sm btn-default" />
<input type="submit" value="Delete" name="action:Delete" class="btn btn-sm btn-danger" />

第 3 步: 现在创建动作过滤器

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class MultipleActionsAttribute : ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public string Argument { get; set; }

        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
        {
            var isValidName = false;
            var keyValue = string.Format("{0}:{1}", Name, Argument);
            var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);

            if (value != null)
            {
                controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
                isValidName = true;
            }
            return isValidName;
        }
    }

第 4 步: 在您的操作上方使用此过滤器:

[HttpPost]
[MultipleActions(Name = "action", Argument = "Edit")]
public ActionResult EditDelete(int id)
{
//Your edit code here
}
[HttpPost]
[MultipleActions(Name = "action", Argument = "Delete")]
public ActionResult EditDelete(int id) // you can pass the id to edit from view 
{
//Your Delete code here
}

【讨论】: