MvcPager2.0在MVC4.0下的"缺陷"及解决方案
说MVCPager2.0在MVC下的”缺陷“,是因为MVCpager不能直接给我想要的ajax局部无刷新的结果,诸位可能要纳闷了,MVC4.0下是可以使用MVCpager2.0来实现局部无刷新呀,网上有很多Demo,是你自己没找到吗,非也,请听我细细道来!
一直在使用.net的MVC框架做项目,做项目不可避免要用到分页,我们之前MVC的版本是3.0,与之搭配的MVCPager的版本是1.x版本。
最常见的使用方式一:
比如在首页的某一块,是一个列表页面,最常见的使用方式是这样子的:
主页面:/home/index
<div id="articles">
@Html.Partial("List",Model)
</div>
子页面:/home/list
其中 Home/list页面以局部视图的方式嵌入到主页面里面。这种方式是最常见的使用方式,在MVC3.0和MVC4.0下都可以使用Ajax无刷新分页,这种使用方式,网上很多很多,在这里就不详细的说了。
使用方式二:
我们公司一直习惯于用这种方式。用jquery来调取列表页面。
比如:这种的,代码如下
<div id="Container">
</div>
<script type="text/javascript">
LoadList($("#Container"), "/home/AjaxPartialLoading");
</script>
其中LoadList使用Jquery的Html函数实现的,
代码如下:
this.LoadList = function (div, url, data, fn) {
if (!$.isEmptyObject(data)) {
url += "?" + $.param(data);
}
$(div).empty();
if ($(div).css("display") == "none") {
$(div).show();
}
$(div).append("<div style='width:100%;height:100%;text-align:center; margin-top:20px;'><img style='float:none;' src='/Content/Images/loading.gif' /></div>");
$.get(url, function (_data) {
$(div).html(_data);
if (fn) fn(_data);
})
}
用这种方式获取列表,有以下几个优点:
1 Ajax是异步处理,用AJax调取页面可以请求多的时候"节省时间"。节省时间是相对而言的,比如有一个网站首页,需要加载很多信息,有用户消息列表,有热销商品排行,等等,如果这些都用Ajax加载,因为Ajax是异步处理,所以服务器可以在同时处理多个请求,最后的时间是以长的时间为准,比如加载一个用户消息列表用1秒,热销商品列表用2秒,加载一个新闻列表用4秒,那么用AJax来加载的话,时间一共是4秒,以最大的时间为准。而用@Html.Partial("List",Model)这种方式,时间是7秒。
2 Ajax,可以尽量避免漫长的等待与错误处理。之前做一个银行的项目,其中有一个模块,数据来源于另外一个系统,和这个系统对接完成之后,正式上线,上线之后出现了一个问题,发现那边提供数据的接口很不稳定,有时候1分多钟才返回数据,有时候直接就抛出异常了,当然我这块做了异常处理,之前我采用的是Html.Partial这种局部视图的方式,这种方式的缺点是同步处理,这块必须必须执行完这块东西之后,才能执行下面的代码,如果接口那边数据出现异常,我这边加载页面就停滞不前了,一直在那里转呀转,这种情况肯定是不行的呀。用户体验太差了,于是我采用了LoadList这种用Jquery来调用列表页的方式。异步去请求这个数据,最后的效果是,那边系统即使出问题了,我一个页面上其他的模块都加载成功了,这块还在加载,最起码没有阻塞我的其他模块,达到我想要的效果了。
这种使用方式在MVC3.0配上MVCPager1.X的版本是没有问题的。
可是我们开发一个新项目,前期是搭建框架,写类库,这次我们用了MVC4.0,网站的大框架都搭好了,类库也写了很多了,开始做具体的页面了,在做页面的过程中,自然要用到分页了,自然我们会用到MVCpager了,可是用的过程中,提示“指定的数组必须具有相同的维数”,最后确定原因是MVC4和MVCPager1.X版本不兼容,后来在网上下载了,MVCPager2,找了下Demo,用的都是Html.Partial这种方式实现的,然后切换成LoadList这种方式实现的Ajax分页,点击下一页时,会直接从Home/Index页面跳出来,
在网上找了很多Demo都没有解决这个问题,最终还是自己用自己写的脚本代替了MVC注册的脚本,最终达到了自己想要的效果
脚本的原理是:用js将a标签的属性和事件进行替换,给a标签注册成自己Onclick事件。实现的js代码其实很简单,主要是提供的这样一种思路,可以不去改MVCPager.dll的源码,实现这种分页的效果。
脚本代码如下:
//divContainer是主页面里面的外层容器Div,DivInner是列表页里面的Div.
this.MvcPager = function (divContainer, divInner) {
$("#" + divInner + "").find("a[data-pageindex]").each(function () {
var link = $(this).attr("href");
var clickAttr = "LoadHtml($(\"#" + divContainer + "\"),\"" + link + "\");return false;";
//地址暂存,供selectchange使用
$(this).attr("newattr", link);
$(this).attr("href", "javascript:void(0)").attr("onclick", clickAttr);
});
$("#" + divInner + "").find("select[data-pageindexbox]").unbind("change");
//注册change事件
$("#" + divInner + "").find("select[data-pageindexbox]").change(function () {
var val = $(this).val();
var url = $("#" + divInner + "").find("a[data-pageindex='" + val + "']").attr("newattr");
//直接用trigger A标签有问题,所以需要重新加载
LoadHtml($("#" + divContainer + ""), url);
});
}
具体使用如下:Demo1.cshtml为网上最常见的用法
Demo2.cshtml为我自定义的用法
项目下载地址如下:https://files.cnblogs.com/tianwang/MvcPage.rar
。
浙公网安备 33010602011771号