你的位置:首页 > ASP.net教程

[ASP.net教程]从头开始一步一步实现EF6+Autofac+MVC5+Bootstarp极简前后台ajax表格展示及分页(二)前端修改、添加表格行点击弹出模态框


在前一篇中,由于不懂jquery,前端做的太差了,今天做稍做修改,增加一个跳转到指定页面功能,表格行点击样式变化。并且在表格中加入bootstarp的按钮组,按钮点击后弹出模态框,须修改common,contorler,view。

在common中添加一个方法重载,以展示按钮组,另外还加了一个隐藏的Id列,需要增加两个参数,一个指定按钮的bootstarp样式,另一个数组指定按钮的名称

修改后的代码如下

using System.Collections.Generic;using System.Text;using Newtonsoft.Json.Linq;namespace OADemo.Common{  public class JsonStringHelper  {    /// <summary>    /// 通过反射将列表中指定的属性值装配成多行多列的Html文本    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="list"></param>    /// <param name="propertyNames">要输出的属性名</param>    /// <returns></returns>    public static string GetTbodyHtmlString<T>(List<T> list,params string[] propertyNames)    {      StringBuilder sb = new StringBuilder();            list.ForEach(o => {        sb.Append(@"<tr>");//做一个行的开始        var properties = o.GetType().GetProperties();//得到当前实体类型的所有属性        foreach (var property in properties)        {          if (propertyNames != null)          {            foreach (var name in propertyNames)            {              if (property.Name==name)              {                string id;                if(name=="Id")                {                  id = property.GetValue(o).ToString();                  sb.AppendFormat(@"<td hidden='hidden'>{0}</td>",id);                }                else                {                  sb.AppendFormat(@"<td>{0}</td>", property.GetValue(o).ToString());                }                              }            }          }                  }        sb.Append(@"</tr>");      });      return sb.ToString();    }    /// <summary>    /// 通过反射将列表中指定的属性值装配成多行多列的json格式的Html文本    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="list"></param>    /// <param name="propertyNames"></param>    /// <returns></returns>    public static JObject GetTbodyJObjectStrin<T>(List<T> list, params string[] propertyNames)    {      return new JObject(new JProperty("tbodyJson", GetTbodyHtmlString(list, propertyNames)));    }    /// <summary>    /// 通过反射将列表中指定的属性值装配成多行多列的json格式的Html文本    /// </summary>    /// <typeparam name="T">要展示的实体类型</typeparam>    /// <param name="list">实体列表</param>    /// <param name="btnNames">按钮的名称</param>    /// <param name="btnClassName">按钮的样式类名</param>    /// <param name="propertyNames">要展示的实体的属性名</param>    /// <returns></returns>    public static string GetTbodyHtmlString<T>(List<T> list,string[] btnNames,string btnClassName,       params string[] propertyNames)    {      StringBuilder sb = new StringBuilder();      list.ForEach(o => {        sb.Append(@"<tr>");//做一个行的开始        var properties = o.GetType().GetProperties();//得到当前实体类型的所有属性        List<string> ids = new List<string>();        foreach (var property in properties)//遍历所有公共属性        {          if (propertyNames != null)          {            foreach (var name in propertyNames)            {              if (property.Name == name)//找出跟要展示的属性名              {                string id;                if (name == "Id")                {                  id = property.GetValue(o).ToString();                  sb.AppendFormat(@"<td hidden='hidden'>{0}</td>", id);//添加一个隐藏列                  ids.Add(id);                }                else                {                  sb.AppendFormat(@"<td>{0}</td>", property.GetValue(o).ToString());//添加其它列                }              }            }          }        }        ids.ForEach(i =>        {                    if(btnNames.Length>0)          {            sb.Append(@"<td><div class='btn - toolbar' role='toolbar'");//bootstarp按钮组            foreach(var name in btnNames)//添加按钮组列            {              sb.AppendFormat(@"<div class='btn-group' role='group'>                      <button class='{0}'>{1}</button>                      </div>",btnClassName,name);            }            sb.Append(@"</div></td></tr>");          }        });      });      return sb.ToString();    }  }}

前端做的修改最多了,之前每一次指定页行数都 要提交两次Ajax请求,实在是太没有水平了,所以现在contorler里只要一个展示表格的方法就行了

修改后的控制器

using MTF.Domain;using MTF.EFDatas;using OADemo.BLL;using OADemo.DataModel.Domains;using System.Linq;using System.Web.Mvc;using Newtonsoft.Json.Linq;using OADemo.Common;namespace OADemo.MVCApp.Controllers{  public class HomeController : Controller  {    //找到相关实体的服务,这里我之前插入500多条数据    private UserBll userService = DependencyContainer.Resolve<UserBll>();    //把分页类当全局属性用    private Pager<UserEntity,int> Pager { get { return userService.Pager; } }    private string[] tabRowNames = new string[] {"Id", "Name", "Age", "RealName", "Email" };//要展示的所有属性    string btnClassName = "btn-info";//指定按钮的bootstarp样式    string[] btnNames = new string[] { "编辑", "删除" };//添加按钮的名称    // GET: Home    public ActionResult Index()    {      Pager.SetPageSize(8);//设置默认值      ViewBag.PageSize = Pager.PageSize;//传值前台默认每页显示的行数      ViewBag.PageCount = Pager.PageCount;//传值前台总页数      var users = Pager.GetPageList(o => o.Id).ToList();//获取以Id排序的列表      var result = JsonStringHelper.GetTbodyHtmlString(users,btnNames,btnClassName, tabRowNames);//装配tbody内容(非必要)      return View(new MvcHtmlString(result));//前台非必要(可直接return View() )    }    /// <summary>    /// 展示表格,类名取的不地道,懒的改了    /// </summary>    /// <param name="pageIndex">当前选中的页码 应该也做成可空类型,懒的改</param>    /// <param name="pageSize">当前页的表格行数</param>    /// <returns></returns>    public ActionResult InitiaTable(int? pageIndex,int? pageSize)    {      //配置可空类型,如果前台没有数据传来,给一个默认值      int size =(int)( pageSize == null ? 8 : pageSize);      int index = pageIndex ?? 1;      //根据前台参数取得相应的数据      var users=Pager.GetPageList(index, size, o => o.Id).ToList();      //配置json格式的html文本      var result = JsonStringHelper.GetTbodyHtmlString(users, btnNames, btnClassName, tabRowNames);      //配置前台必要的json格式数据,分别为页总数,表格内容,指定页的行数      var jo = new JObject(new JProperty("pageCountJson", Pager.PageCount),        new JProperty("tbodyJson", result),        new JProperty("pageSizeJson",Pager.PageSize));      return Content(jo.ToString());    }      }}

修改后的前端

@{  Layout = null;}<!DOCTYPE html><html><head>  <meta charset="utf-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge">  <meta name="viewport" content="width=device-width, initial-scale=1">  <link href="~/Content/bootstrap.min.css" rel="stylesheet" />  <script src="~/scripts/jquery-1.9.1.min.js"></script>  <script src="~/scripts/bootstrap.min.js"></script>  <script src="~/scripts/jqPaginator.min.js"></script>  <style type="text/css">    .modal-content{      background-color:#734BA9;      color:white;    }  </style>  <script type="text/javascript">    var pageCount= @ViewBag.PageCount;//总页数    var pageSize= @ViewBag.PageSize;//每页显示数量        $(function () {       //加载分页      LoadPager(pageSize,1);       //设置每页行数按钮      $("#btnSetPageSize").click(function(){        var size=Number($("#pageSize").val());        //当无值时给默认值        if(size==0){          size=pageSize;        }        LoadPager(size,1);      })      //跳转页面按钮      $("#pageIndex").change(function(){        //当输入框无值时,默认给1        var index=Number($("#pageIndex").val());        if(index==0){          index=1;        }        LoadPager(pageSize,index);      })          })    //单选时表格行的点击事件函数    function SingleSelect(){      if($(this).hasClass("success")){        $(this).removeClass("success");      }      else{        $(this).addClass("success").siblings().removeClass("success");      }    }    //多选时表格行的点击事件函数    function ManySelect(){      if($(this).hasClass("success")){        $(this).removeClass("success");      }      else{        $(this).addClass("success");      }    }       //按钮的点击事件    function OnTd_ButtonClick(){      //如果是编辑按钮      if($(this).text()=="编辑"){        var values=new Array//用于存放当前行中列的内容的数组                var td=$(this).parents("td");//找出当前按钮所在的列        var uid=$(td).siblings("td:hidden").text();//获取隐藏列的内容        var n=$(td).siblings("td:not(:hidden)").length;//不包含隐藏属性的其它(兄弟)列的数量        for(var a=0;a<n;a++){          values.push($($(td).siblings("td:not(:hidden)")[a]).text());//添加内容到数组        }        $("#addModalLabel").text("当前正在编辑用户:"+values[0]);        $('#addModal').modal('show')        $("#btnEdit").click(function(){          $('#addModal').modal('hide')        })      }      //如果是其它,这里只有两个所以直接else了      else{      }    }    //加载分页    function LoadPager(size,index){      $('#pager').jqPaginator({        totalPages: pageCount,        visiblePages: 8,        currentPage: index,        first: '<li ><a href="javascript:;">首页</a></li>',        prev: '<li ><a href="javascript:;">上一页</a></li>',        next: '<li ><a href="javascript:;">下一页</a></li>',        page: '<li ><a href="javascript:;">{{page}}</a></li>',        last: '<li ><a href="javascript:;">尾页</a></li>',        onPageChange: function (num,type) {          //页码改变时的Ajax方法          $.post("/Home/InitiaTable/",            {pageIndex:num,pageSize:size},            //表格加载回调函数            function (data){                           var json=eval("("+data+")");//转换JSON格式                            var tbodyHtml=json.tbodyJson;//获取表格数据              //修改分页器的总页数              $('#pager').jqPaginator('option', {                totalPages: json.pageCountJson              });              if(num!=pageCount){                pageSize=json.pageSizeJson;//更新当前页的行数              }                                         pageCount=json.pageCountJson;//更新总页数                            $("#table tbody").empty().append(tbodyHtml);//更新表格              $("#table tbody").children("tr").click(SingleSelect);//表格行的点击样式              $("#table tbody tr td button").click(OnTd_ButtonClick);//按钮的点击事件            })        }      });    }          </script>  <title>Index</title></head><body>  <!--编辑模态框-->  <div class="modal fade bs-example-modal-sm" id="addModal" tabindex="-1" role="dialog"     aria-labelledby="addModalLabel" aria-hidden="true">    <div class="modal-dialog">      <div class="modal-content">        <!--头部-->        <div class="modal-header">          <button type="button" class="close" data-dismiss="modal"              aria-hidden="true">            ×          </button>          <h4 class="modal-title" id="addModalLabel"></h4>        </div>        <!--正文-->        <div class="modal-body">          <form class="form-horizontal" role="form">            <div class="form-group">              <label for="userName" class="col-sm-2 control-label">用户名</label>              <div class="col-sm-10">                <input type="text" class="form-control" id="userName">              </div>            </div>            <div class="form-group">              <label for="nickName" class="col-sm-2 control-label">昵称</label>              <div class="col-sm-10">                <input type="text" class="form-control" id="nickName">              </div>            </div>            <div class="form-group">              <label for="email" class="col-sm-2 control-label">邮箱</label>              <div class="col-sm-10">                <input type="text" class="form-control" id="email">              </div>            </div>            <div class="form-group">              <label for="password" class="col-sm-2 control-label">密码</label>              <div class="col-sm-10">                <input type="password" class="form-control" id="pasword">              </div>            </div>          </form>        </div>        <!--尾部-->        <div class="modal-footer">          <button type="button" class="btn btn-default"              data-dismiss="modal">            关闭          </button>          <button type="button" class="btn btn-primary" id="btnEdit">            提交更改          </button>        </div>      </div>    </div>  </div>  <div class="container text-center" >            <!--表格面板-->    <div class="row" >      <div class="col-md-12">        <div class="panel panel-primary">          <div class="panel-heading text-left">            用户列表                      </div>          <div class="panel-body">                                  <table class="table" id="table">              <thead>                <tr>                  <td>Name</td>                  <td>Age</td>                  <td>Email</td>                  <td>RealName</td>                  <td>Actions </td>                </tr>              </thead>              <tbody>              </tbody>            </table>          </div>        </div>      </div>    </div>    <!--分页组件-->    <div class="row">      <div class="col-md-7">        <!--分页-->         <ul id="pager" class="pagination">          <li>                     </li>         </ul>                             </div>      <!--跳转到指定页-->      <div class="col-md-2"style="margin-top:25px">        <label for="pageIndex">跳转</label>        <input type="text" style="width:40px" id="pageIndex"/>      </div>      <!--设定每页显示的数量-->      <div class="col-md-3 " style="margin-top:25px">        <label for="pageSize" >设置每页行数</label>        <input type="text" style="width:40px" id="pageSize" placeholder="8"/>        <button type="button" class="btn-info" id="btnSetPageSize">设置</button>       </div>          </div>      </div></body></html>

看看效果,现在是指定到第9页,单击其中一行,添加了样式

后面的按钮组也出现了。现在只做了其中的“编辑”按钮点击事件,点击后弹出模态框

模态框中的用户名显示绑定的是当前点击的行的用户名。就做到这里了。后面的工作没有去实现了,实现也没有意义,只能当是玩玩,在这过程中起码对jquery有了入门级别的了解了,收获还是不小的。

这里看到一篇文章,用的刚好是这方面的专业插件。比自己瞎捣鼓的肯定要好些。标题跟我的差不多,不过他的多搜索功能,并且专业,我的全是自定义

MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分页

表格,分页就到此了,希望以后能有时间做一个真正简单的AODemo

哦,对了,前端有个BUG,我不知道是我代码的问题还是分页插件的BUG,就是有时候我点尾页或是其它跳得比较远的页面时,会找不到表格行的所有事件,就像是没有行存在,但是数据已经加载过来,并且没有错。这个问题不是百分百出现,只是常有,只要点一下其它不是表格的控件,或是再点一下页码,又会好。想了三天了,都想不出是什么原因。如果有幸有大牛经过,希望能指点一下迷津!!!