在向导中动态 add/remove table 行

Dynamically add/remove table rows in a wizard

我目前正在我的应用程序中使用这个Wizard

在我的步骤之一中,我需要在 table 中添加和删除项目。添加功能工作正常。但是我无法使删除功能起作用。我在网上搜索了 SO 和其他资源,找不到解决方案。

这是我目前的情况:

向导步骤 2 Table:

  <table id="LibList" class="table table-responsive table-striped">
            <thead>
                <tr>
                    <th>
                        @Html.DisplayNameFor(model => model.Step3.Liabilities[0].Types)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Step3.Liabilities[0].Name)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Step3.Liabilities[0].Teams)
                    </th>
                    <th>
                        <label>Delete</label>
                    </th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model.Step3.Liabilities) {
                    Html.RenderPartial("_LibListItem", item);
                }
            </tbody>
        </table>

局部视图:

        <tr>
<td>
    @Html.DropDownListFor(model => model.Type, Model.Types, new { @class = "selectpicker form-control", id = string.Format("{0}_{1}", "TYPE", Model.ID) })
</td>
<td>
    @Html.TextBoxFor(model => model.Name, new { @class = "form-control", id = string.Format("{0}_{1}", "NAME", Model.ID) })
</td>
<td>
    @Html.TextBoxFor(model => model.Teams, new { @class = "form-control", @type = "currency", id = string.Format("{0}_{1}", "TERMS", Model.ID) })
</td>
<td>
    @Ajax.ActionLink("Delete", "Delete", "QuestionWizard", new { id = Model.ID },
    new AjaxOptions() {
        HttpMethod = "Delete",
        Confirm = "Are you sure you want to delete this record?",
        OnComplete = "function() { $(this).parent().parent().remove() }"
    },
    new { @class = "btn btn-primary" })
</td>

添加和删除操作:

    public ActionResult AddRow() {
        LiabilityModel lib = new LiabilityModel();
        try {
            if (LiabilitySessionState.Count == 0) {
                lib.ID = 1;
            } else {
                lib.ID = LiabilitySessionState.LastOrDefault().ID + 1;
            }
            LiabilitySessionState.Add(lib);
            return PartialView("_LibListItem", lib);
        } catch (Exception ex) {
            System.Web.HttpContext.Current.Application.Add("LASTERROR", ex);
            return RedirectToAction("Index", "Error");
        }
    }

    public void Delete(int Id) {
        try {
            if (LiabilitySessionState.Count > 0) {
                LiabilitySessionState.RemoveAll(item => item.ID == Id);
            }
        } catch (Exception ex) {
            System.Web.HttpContext.Current.Application.Add("LASTERROR", ex);
            RedirectToAction("Index", "Error");
        }
    }

    public List<LiabilityModel> LiabilitySessionState {
        get {
            if (Session["LiabilityModel"] == null) {
                return LiabilitySessionState = new List<LiabilityModel>();
            } else {
                return Session["LiabilityModel"] as List<LiabilityModel>;
            }
        }
        set {
            Session["LiabilityModel"] = value;
        }
    }

脚本:

<script type="text/javascript">
$(document).ready(function () {
    $('.add-button').click(function () {
        var action = "/QuestionWizard/AddRow";
        $.ajax({
            url: action,
            cache: false,
            success: function (result) {
                $("#LibList tbody").append($(result));
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {

            }
        });
    })
    $(".remove-button").click(function () {
        $(this).parents().parent().remove();
        return false;
    });
});

现在,删除操作 return 是一个空白页,因为我没有 return 查看。但是,我不确定 return.

的观点是什么

请帮忙!

提前致谢。

首先,您的 Delete() 方法正在更改数据,因此它需要是 POST,而不是 GET(@Ajax.ActionLink() 是)。接下来,你的 'delete link' 没有 class="remove-button" 所以 $(".remove-button").click(function () { 不会做任何事情。由于您已经使用 jquery ajax 方法来添加项目(请参阅下面的注释),因此无论如何使用 Ajax 助手似乎没有意义(您只是通过加载 jquery.unobtrusive-ajax.js 文件)。

将部分的最后一个 <td> 元素更改为

<td>
  <button type="button" class="remove-button" data-id=@Model.ID>Delete</button>
</td>

然后在主视图中,使用以下脚本(注意您需要事件委托,以便您可以删除动态添加的项目)

var url = '@Url.Action("Delete", "YourControllerName")';
$('#LibList').on('click', .remove-button, function() {
  var row = $(this).closest('tr');
  var id = $(this).data('ID');
  if (id) { // assumes property ID is nullable, otherwise may need to test if id != 0
    $.post(url, {ID: id }, function(response) {
      if(response) {
        row.remove();
      } else {
        // Oops - display message?
      }
    });
  } else {
    // its a new row so it has not been saved yet - just delete the row
    row.remove();
  }
});

控制器方法应该类似于

[HttpPost]
public JsonResult Delete(int ID)
{
  // delete the item
  return Json(true); // or if an exception occurred, return(null) to indicate failure
}

旁注:

  1. 您的 AddRow()Delete() 方法都包含一个 return RedirectToAction() 语句。您正在进行 ajax 次通话 在同一页上,所以 RedirectToAction() 毫无意义(它永远不会 被处决)
  2. 如果你相信"Add functions works fine",那你一定有 为了使这项工作进行一些不必要的黑客攻击(您的生成 控件的重复 name 属性(没有索引器) 它不会绑定到您的 Liabilities 集合)。你需要 在 for 循环中生成现有项目并包含一个隐藏项 输入 Index 属性,并使用客户端模板 生成新项目;或者您需要使用 BeginCollectionItem 如果使用局部视图,则为助手。 这个 回答 展示了如何使用这两种技术。
  3. 你没有出现(你应该不需要)访问 id table 中控件的属性。不要使用 id = string.Format("{0}_{1}", "NAME", Model.ID),只需使用 id="" 将呈现没有 id 属性的元素。