如何在MVC中动态添加模型列表值?

时间:2015-06-30 06:57:20

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

我有一个模型列表,我使用该模型将值显示在表中。 在该表上,如果我添加新行意味着它正在添加新行,但在模型列表中它没有绑定。

我的模特:

public class ApplicationInfo
{
    [Display(Name = "Business Unit")]
    [Required(ErrorMessage = "Business Unit is required")]
    public int biz_unit_key { get; set; }

    [Display(Name = "Application Short Code")]
    [Required(ErrorMessage = "Application Short Code is required")]
    [StringLength(10, ErrorMessage = "Application Short Code length should be less than or equal to 100")]
    public string app_short_code { get; set; }

    [Display(Name = "Application Name")]
    [Required(ErrorMessage = "Application Name is required")]
    [StringLength(10, ErrorMessage = "Application Name length should be less than or equal to 100")]
    public string app_name { get; set; }

    public List<ApplicationAccessRoles> ApplAccessRoleInfo { get; set; }      
    }

    public class ApplicationAccessRoles
    {
        public int app_access_role_key { get; set; }
        public int app_key { get; set; }
        public string access_role { get; set; }
        public bool inactive { get; set; }
    }

我的观点:

<table id="RolesDetails" cellpadding="0" cellspacing="0" class="data_table">
    <tr class="dataheader">
        <td class="width5">
            &nbsp;
            @Html.HiddenFor(m => m.app_access_role_key)
        </td>
        <td class="width200">
            Access Roles Name
        </td>
        <td class="width10">
            Inactive
        </td>                         
    </tr>

    @if (Model.ApplAccessRoleInfo.Count!= 0) // class-2 for populate data in table 
    {
        var chk = Model.ApplAccessRoleInfo.Count;
        for (int a = 0; a < Model.ApplAccessRoleInfo.Count; a++)
        {
            <tr class="exp_col_header top_border_nil">
                @if ((chk - 1) == a)
                { 
                    <td><a href="#" class="gridexpand" rel="1"></a></td> @* for add new row *@
                }
                else
                {
                    <td></td>
                }

                <td>
                    @Html.HiddenFor(m => m.ApplAccessRoleInfo[a].app_access_role_key)
                    @Html.EditorFor(m => m.ApplAccessRoleInfo[a].access_role)
                </td>
                <td>
                    @Html.CheckBox("ApplTeamAccessInfo[" + a.ToString() + "].inactive", false, new { @class = "check-box" })
                </td>
            </tr>
        }
    }
    else
    {
        <tr class="exp_col_header top_border_nil">
            <td>
                <a href="#" class="gridexpand" rel="1"></a> @* for add new row *@    
            </td>
            <td>
                @*@Html.EditorFor(model => model.access_role)*@
                @*@Html.EditorFor(m => m.ApplAccessRoleInfo[0].access_role)*@
                @Html.EditorFor(model=>model.access_role)
            </td>
            <td>
                @Html.CheckBoxFor(model => model.inactive)
            </td>
        </tr>                         
    }
</table>

<table id="newrow" style="display:none">
    <tr class="exp_col_header top_border_nil">
        <td>
            <a href="#" class="gridexpand" rel="1"></a>
        </td>
        <td>
            <input data-val="true" data-val-number="The field app_access_role_key must be a number." data-val-required="The app_access_role_key field is required." name="ApplAccessRoleInfo[#].app_access_role_key" type="hidden" value="#">
            <input class="text-box single-line" name="ApplAccessRoleInfo[#].access_role" type="text" value="#">
        </td>
        <td>
            <input class="check-box" name="ApplTeamAccessInfo[#].inactive" type="checkbox" value="false"><input name="ApplTeamAccessInfo[#].inactive" type="hidden" value="false">
        </td>
    </tr>
</table>

我的jQuery用于向表中添加新行:

$(".gridexpand").click(function (event) {
    @*
        @Html.HiddenFor(m => m.ApplTeamAccessInfo[a].app_access_role_key)
        @Html.EditorFor(m => m.ApplTeamAccessInfo[a].access_role) 

        <table id="RolesDetails" cellpadding="0" cellspacing="0" class="data_table"> 
    *@

    var tablebody = $('#RolesDetails'); // modify to suit your id
    var newrow = $('#newrow');
    var index = 0; // unique indexer
    var clone = newrow.clone(); // clone the new row

    alert("new row");
    clone.html($(clone).html().replace(/#/g, index)); // update the indexer of the clone
    var row = clone.find('tr');
    tablebody.append(row); 
});

我的控制器

  public ActionResult Index(int? id)
        {
        ApplicationInfo AppInfo = new ApplicationInfo();

        List<ApplicationAccessRoles> access = new List<ApplicationAccessRoles>();
        mas_app_access_roles roles;


        mas_apps application;
        UserInfo oUser = (UserInfo)Session["UserInfo"];
        if (id == null || id == 0)
        {
            application = new mas_apps();
            roles = new mas_app_access_roles();
            application.Applications = db.mas_apps.ToList();
        }
        else
        {
            application = db.mas_apps.Find(id);

                roles = db.mas_app_access_roles.Find(id);
                AppInfo.app_access_role_key = roles.app_access_role_key;
                AppInfo.app_key = roles.app_key;
                //AppInfo.access_role = <IEnumerable>roles.access_role;
                AppInfo.inactive = roles.inactive;
                AppInfo.created_by = roles.created_by;
                AppInfo.created_date = roles.created_date;
                AppInfo.last_modified_by = roles.last_modified_by;
                AppInfo.last_modified_date = roles.last_modified_date;

        var main = (from a in db.mas_app_access_roles
                    where a.app_key == AppInfo.app_key
                    select new ApplicationAccessRoles
                    {

                        app_access_role_key = a.app_access_role_key,
                        access_role = a.access_role,
                        inactive = a.inactive,
                    }
                    ).ToList();
        access = main;
        AppInfo.ApplAccessRoleInfo = access;
        ViewBag.check = access;
        return View(AppInfo);
    }

并在编辑后保存表格

if (ModelState.IsValid)
        {
            UserInfo oUser = (UserInfo)Session["UserInfo"];
            if (app.app_key == 0)
            {
                mas_apps appInfo = new mas_apps();
                appInfo.app_key = 0;
                appInfo.biz_unit_key = app.biz_unit_key;
                appInfo.app_short_code = app.app_short_code;
                appInfo.app_name = app.app_name;
                appInfo.app_version = app.app_version;
                db.mas_apps.Add(appInfo);
            }
            else
            {
                mas_apps appInfo = new mas_apps();
                appInfo.app_key = app.app_key;
                appInfo.biz_unit_key = app.biz_unit_key;
                appInfo.app_short_code = app.app_short_code;
                db.Entry(appInfo).State = EntityState.Modified;
                db.Entry(appInfo).Property("created_by").IsModified = false;
                db.Entry(appInfo).Property("created_date").IsModified = false;

            }


            if (app.ApplAccessRoleInfo != null)
            {
                foreach (ApplicationAccessRoles pvInfo in app.ApplAccessRoleInfo)///---------------------in this loop its not fetching the newly added row
                {
                            mas_app_access_roles tv = new mas_app_access_roles();

                            //db.mas_app_access_roles.Add(tv);
                            if (pvInfo.app_access_role_key == 0)
                            {
                                tv.app_key = app.app_key;
                                tv.app_access_role_key = pvInfo.app_access_role_key;
                                tv.access_role = pvInfo.access_role;
                                tv.inactive = pvInfo.inactive;
                                tv.created_by = oUser.User.user_key;
                                tv.created_date = DateTime.Now;
                                tv.last_modified_by = oUser.User.user_key;
                                tv.last_modified_date = DateTime.Now;
                                db.mas_app_access_roles.Add(tv);
                                db.SaveChanges();
                            }
                            else
                            {

                                tv.app_key = app.app_key;
                                tv.app_access_role_key = pvInfo.app_access_role_key;
                                tv.access_role = pvInfo.access_role;
                                tv.inactive = pvInfo.inactive;
                                tv.created_by = oUser.User.user_key;
                                tv.created_date = DateTime.Now;
                                tv.last_modified_by = oUser.User.user_key;
                                tv.last_modified_date = DateTime.Now;
                                db.Entry(tv).State = EntityState.Modified;
                                db.SaveChanges();
                                //db.Entry(tv).Property("created_by").IsModified = false;
                                //db.Entry(tv).Property("created_date").IsModified = false;
                            }
                            db.SaveChanges();
                }
            }

1 个答案:

答案 0 :(得分:1)

首先,您需要在用于生成现有项目的循环中为Index属性添加隐藏输入。这将确保在您提交

时不能将连续的索引器绑定到集合
for (int a = 0; a < Model.ApplAccessRoleInfo.Count; a++)
{
  <tr>
    <td>
      @Html.HiddenFor(m => m.ApplAccessRoleInfo[a].app_access_role_key)
      @Html.EditorFor(m => m.ApplAccessRoleInfo[a].access_role)
    </td>
    <td>
      @Html.CheckBoxFor(ApplTeamAccessInfo[a].inactive) // use CheckBoxFor()
      <input type="hidden" name="ApplTeamAccessInfo.Index" value="@a" /> // add this
    </td>
  </tr>
}

接下来,您需要检查为其中一行生成的html并根据该模板生成模板。您还需要包含Index属性的隐藏输入,如上所示。您还需要删除inactive属性的2个输入的值属性(或将其设置为属性的默认值),其中值必须为"true)"false"(目前它们都是"false"。它看起来像(注意:为了简单起见,删除了data-*属性)

<table id="newrow" style="display:none">
  <tr>
    <td>
      <input name="ApplAccessRoleInfo[#].app_access_role_key" type="hidden" >
      <input name="ApplAccessRoleInfo[#].access_role" type="text" >
    </td>
    <td>
      <input class="check-box" name="ApplTeamAccessInfo[#].inactive" type="checkbox" value="true"> // change value to true
      <input name="ApplTeamAccessInfo[#].inactive" type="hidden" value="false">
      <input type="hidden" name="ApplTeamAccessInfo.Index" value="#" /> // add this
    </td>
  </tr>
</table>

然后脚本需要

var form = $('form'); // or use the id if you have given the form an id
var newrow= $('#newrow');
var table = $('#RolesDetails');
$(".gridexpand").click(function() {
  var index = (new Date()).getTime(); // unique indexer
  var clone = newrow.clone(); // clone the new row
  clone.html($(clone).html().replace(/#/g, index)); // update the indexer of the clone
  var row = clone.find('tr');
  table.append(row); // add the new row to the table
  // Reparse the validator
  form.data('validator', null);
  $.validator.unobtrusive.parse(form);
});

在脚本中请注意,您需要为索引器标识的唯一标识符var index = (new Date()).getTime();所执行的操作(当前您将其设置为"0",但第一行已经有"0"的索引器)

另请注意,由于您的属性具有验证属性,因此需要在添加新行时重新解析验证程序。