在向导中动态添加/删除表行

时间:2015-02-28 18:59:02

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

我目前正在申请中使用此Wizard

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

这是我到目前为止:

向导第2步表:

  <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;
    });
});

现在,删除操作返回一个空白页面,因为我没有返回视图。但是,我不确定要回归的观点。

请帮忙!

提前致谢。

1 个答案:

答案 0 :(得分:1)

首先,您的Delete()方法正在更改数据,因此它需要是POST,而不是GET(@Ajax.ActionLink()是)。接下来,您的“删除链接”没有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. 如果您认为“添加功能正常”,那么您必须拥有 一些不必要的黑客为了使这项工作(你的生成 控件的重复name属性(没有索引器) 它不会绑定到您的Liabilities集合。你需要 在for循环中生成现有项并包含隐藏项 输入Index属性,并使用客户端模板 生成新项目;或者您需要使用BeginCollectionItem 如果使用局部视图,则为助手。 This answer 展示了如何使用这两种技术。
  3. 您没有出现(并且您不应该)访问id 表格中控件的属性。不要使用id = string.Format("{0}_{1}", "NAME", Model.ID),而只使用id="" 将使用id属性渲染元素。