基於jqgrid + ashx + nhibernate的分頁

因為我目前運維的是一個webform項目,項目中未用到分頁的功能,我百度了很多文章也沒有一篇是結合jqgrid + ashx + nhibernate的分頁,可能是因為後台要請求ashx的原因,不像mvc直接可以請求一個方法就可以了。

那就讓我們從頁面到後台來一步步解析jqgrid的分頁吧。

 

1、初始化表格的程式碼如下

 function initGrid() {
        
        localGrid = jQuery("#tbList");
        localGrid.jqGrid({
            //data: localData,
            url:"JqgridPageHandler.ashx",
            datatype: "json",
            gridview: true,
            height: 300,
            width: '95%',
            rowNum: 10,
            rowList: [10, 100, 500, 1000],
            colNames: columns,
            autowidth: true,
            hoverrows: false,
            colModel: [
                { name: 'Id', hidden: true, index: 'Id', width: 40, key: true },
                { name: 'Name', index: 'Name', width: 40, align: "center" },
                { name: 'ExamType', index: 'ExamType', width: 100, align: "center" },
                { name: 'Score', index: 'Score', width: 30, align: "center" },
                { name: 'QuerySite', index: 'QuerySite', width: 120, align: "center" },
                { name: 'ExamTime', index: 'ExamTime', width: 60, formatter: "date", formatoptions: { srcformat: 'Y-m-d ', newformat: 'Y-m-d ' }, align: "center" },
                { name: 'CreatedTime', index: 'CreatedTime', width: 60, formatter: "date", formatoptions: { srcformat: 'Y-m-d ', newformat: 'Y-m-d ' }, align: "center" },
                { name: 'StatusText', index: 'StatusText', width: 50, align: "center" },
                { name: 'Remark', index: 'Remark', width: 120, align: "center" }
            ],
            emptyrecords: "沒有任何數據",
            pager: "#pager",
            viewrecords: true,
            rownumbers: true,
            //loadonce: true,
            caption: "外語成績單",
            multiselect: false,
            postData: {//參數
                name: $j("#name").val(),
                examType: $j("#examType").val(),
                startDate: startDate,
                endDate: endDate,
                isCreateTime: document.getElementById("<%=rbcreatedtime.ClientID %>").checked
            },
            jsonReader: {
                //rows: "rows",
                //page: "page",
                //total: "total",          //   很重要 定義了 後台分頁參數的名字。
                //records: "records",
                repeatitems: false,
                
            }



        }).navGrid('#pager', { edit: false, add: false, del: false, searchtext: "搜索" }, {}, {}, {}, { search: true, sopt: ['cn', 'eq', 'ge', 'gt', 'le', 'lt'] });

        gridHelper.SetAutoResize(localGrid, -20, -265, true, true);
    }

在這個初始化表格的程式碼中有幾點是要注意的:

a. jsonReader中只要設置repeatitems 為 false就可以了 其它的被注掉的參數是默認的。

b. postData 參數是我們查詢的條件。在調用這個方法時要初始化好參數對應的值。例如:startDate  和  endDate

2、在頁面的JS執行入口載入數據可以這樣寫

 

jQuery(document).ready(function () {
        initDate();
        initGrid();
    });

 

initDate()方法就是為了初始化參數的 startDate  和  endDate 的值

3、當我們進入頁面時會調用2中的方法進入後台 JqgridPageHandler.ashx 中的ProcessRequest方法,我們再進入這個方法中看他是如何接收參數和構造返回值的吧.
 public void ProcessRequest(HttpContext context)
        {
            int pageSize = int.Parse(context.Request["rows"]);
            int pageIndex = int.Parse(context.Request["page"]);
            string name = context.Request["name"].ToString();
            string examType = context.Request["examType"].ToString();
            DateTime startDate =DateTime.Parse(context.Request["startDate"].ToString());
            DateTime endDate = DateTime.Parse(context.Request["endDate"].ToString());
            bool isCreateTime =bool.Parse(context.Request["isCreateTime"].ToString());

            List<OilDigital.CGGL.BLL.Abroad.ES> eslist = ESService.GetByPage(isCreateTime, startDate, endDate, ProfileHelper.GetUnitCode(), name, examType, pageSize, pageIndex);
            ISession session = NHibernateSessionManager.Instance.GetSession();
            int count = ESService.GetCount(isCreateTime, startDate, endDate, ProfileHelper.GetUnitCode(), name, examType);
            var resultJson = new

            {

                count = count,

                page = pageIndex,

                //總頁數=(總頁數+頁大小-1)/頁大小

                total = (int)Math.Ceiling(((double) count) / pageSize),//總頁數

                rows = eslist

            };
            context.Response.ContentType = "application/json; charset=utf-8";
            context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(resultJson));
            
        
        }

context.Request["page"],context.Request["rows"]這個中的rows是jqgrid默認往後台傳的參數,其它參數的都是我們在頁面上通過postData構造的。
再看看我們返回的參數吧,前端頁面要接收一個json的對象,其中rows中包括了行,total就總頁數,count是總條數,page是當前頁面。這樣傳到前台去就可以了。

另外我們頁面上肯定還會加一個查詢的按鈕,點擊查詢時會重新去載入jqgrid.程式碼如下:
    function doQuery() {
        initDate();
        localGrid.jqGrid('clearGridData');
        localGrid.jqGrid('setGridParam', {
            url: 'JqgridPageHandler.ashx',
            postData: {
                name: $j("#name").val(),
                examType: $j("#examType").val(),
                startDate: startDate,
                endDate: endDate,
                isCreateTime: document.getElementById("<%=rbcreatedtime.ClientID %>").checked
            },
            datatype: "json",
            mtype: 'post',
        }).trigger('reloadGrid');

    }

因為在用戶點擊查詢時可能會修改查詢程式碼,那postData這裡帶上修改後的查詢程式碼是很重要的。



4、我們再來看看ESService.GetByPage 和 ESService.GetCount 方法是如何在NHibernate中實現的吧
  public List<ES> GetByPage(bool isCreateTime,DateTime startDate, DateTime endDate, string unitCode, string name, string examType, int pageSize, int pageNumber)
        {
            try
            {
                ISession session = NHibernateSessionManager.Instance.GetSession();
                ICriteria criteria = session.CreateCriteria(typeof(ES));
                if(isCreateTime)
                {
                    criteria.Add(Expression.Between("CreatedTime", startDate, endDate));
                }
                else
                {
                    criteria.Add(Expression.Between("ExamTime", startDate, endDate));
                }
                
                if (!string.IsNullOrEmpty(unitCode))
                    criteria.Add(Expression.Like("CeaterUnitCode", unitCode.Trim() + "%"));
                if (!string.IsNullOrEmpty(name))
                {
                    criteria.Add(Expression.Eq("Name", name.Trim()));
                }
                if (!string.IsNullOrEmpty(examType))
                {
                    criteria.Add(Expression.Like("ExamType", "%" + examType.Trim() + "%"));
                }
                criteria.AddOrder(Order.Desc("CreatedTime"));
                criteria.SetFirstResult((pageNumber - 1) * pageSize);
                criteria.SetMaxResults(pageSize);
                return ConvertToGenericList(criteria.List());
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

這裡面可以看到分頁方法 SetFirstResult  和 SetMaxResults   其它都是加的一些查詢條件。

這個方法只是獲取了分頁的數據,現在還需要獲取總的數據條數,請看如下的方法:

public int GetCount(bool isCreateTime,DateTime startDate, DateTime endDate, string unitCode, string name, string examType)
        {
            StringBuilder sb = new StringBuilder();
            if(isCreateTime)
            {
                sb.AppendFormat("select count(*) from ES as es where es.CreatedTime between  convert(datetime,'{0}',111) and convert(datetime,'{1}',111)", startDate, endDate);
            }else
            {
                sb.AppendFormat("select count(*) from ES as es where es.ExamTime between  convert(datetime,'{0}',111) and convert(datetime,'{1}',111)", startDate, endDate);
            }
            
        
               if(!string.IsNullOrEmpty(unitCode))
               {
                   sb.AppendFormat(" and es.CeaterUnitCode like '{0}%'", unitCode.Trim());
               }
   

            if(!string.IsNullOrEmpty(name))
            {
                sb.AppendFormat(" and es.Name = '{0}'", name);
            }
            if(!string.IsNullOrEmpty(examType))
            {
                sb.AppendFormat(" and es.ExamType like '%{0}%'", examType);
            }
            IEnumerator enumerator = session.CreateQuery(sb.ToString()).List().GetEnumerator();
            enumerator.MoveNext();
            return (int)enumerator.Current;
        }

查詢數據總條數是我是通過sql寫的,暫時我也沒有發現是否可以通過Expression表達式寫,就像上面的查詢數據的方法一樣。如果可以那會省一次事,不用還去搞sql.

到此從前端到後端所有的程式碼都講解完了,後台項目的中都可以用這個分頁的方法了。

 

有需要大量進行微信投票或點贊的朋友可以給我留言哦!

 

 

 

Tags: