使用异步controller与jQuery实现卷帘式分页


Posted in jQuery onJune 18, 2019

问题

今天很多网站与数据库交互。如果您的网站接收大量的流量,SQL查询来检索数据,是相当激烈的。更重要的是因为普通用户点击一个在15秒内到达您的网站的链接, 检索和生成内容的工作可能是不必要的,尤其是当内容是“地域折叠”(不滚动是不可见的)。为了帮助解决这个问题,内容将被“按需”载入。足够的内容将被载入,使页面感觉起来是随用户向下滚动阅读递增的,更多的内容将在不影响用户体验的场景下填充。

解决方案

使用异步controller与jQuery按需加载内容,当用户开始通过网站的内容滚动时进一步加载内容。

讨论

异步controller可能在许多MVC应用中未充分利用。最有可能的是因为人们不知道他们,更重要的是,不知道何时使用它们。以下是摘录见MSDN网站:

“在应用中,线程饥饿可能会发生,您可以配置action 异步处理。异步请求和同步请求过程需要相同的时间例如,如果一个请求,使得网络调用需要两秒钟来完成的,请求需要两秒钟,无论是执行同步或异步。然而,在一个异步调用,当服务器响应等待它的第一次请求时完成时他响应其他的请求没有被阻塞。因此,当有许多请求调用长时间运行的操作时,异步请求会防止请求排队。“

在这个例子里,异步请求是完美的解决方案。因为他会让IIS服务器有能力去处理更多重要的请求,比如一个新的用户第一次访问网站。其中,加载用户点播内容是不太重要,因为大多数人甚至不关注被加载额外的内容。在一个典型的社交网站,大多数活动可能包含用户的意见。在以前的秘方中,创建了一个评论的功能。

在这个例子中,将更新网站的网页,列出最近的评论。足够的评论会被显示,所以会出现滚动条。一旦用户开始滚动,一个Ajax请求异步controller将检索其他评论。

首先Home/Index view 需要更新去显示最近的评论。为了提供一些评论的上下文内容,关于书的基础详情也将被显示为导航到图书的链接。所以这个view将简单的调用view 中的render function会在下边创建:

@model IEnumerable<MvcApplication.Models.BookComment>
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" rel="external nofollow" title="ASP.NET MVC Website">
http://asp.net/mvc</a>.
</p>
<script type="text/javascript">
var lastY = 0;
var currentY = 0;
var page = 1;
var maxPages = @ViewBag.maxPages;
$(window).scroll(function () {
if (page < maxPages) {
currentY = $(window).scrollTop();
if (currentY - lastY > 200 * (page - 1)) {
lastY = currentY;
page++;
$.get('CommentFeed/Comments?page=' + page,
function(data) {
$('#comments').append(data);
});
}
}
});
</script>
<div id="comments">
<h2>
Recent Comments</h2>
@Html.Partial("../CommentFeed/Comments", Model)
</div>

在上面的例子,执行滚动窗口时也有一些比较复杂的JavaScript代码会执行。一些全局JavaScript变量被定义去保持监控当前的“Y”滚动的位置,最后的“Y”滚动位置和当前被检索的页面。当窗口的scrollTop位置减去最后的滚动位置是大于一个具体的数字,通过Ajax检索新书评论并附加到评论列表。

你将根据你自己的网站去根据矫正那个具体的数字,基于内容的高度,要确保新的内容总是要提前检索。

下一步,HomeController需要更新检索图书评论列表。 评论在降序排序,以确保最新的创建日期评论首先显示。为了防止激烈的数据库负载,全部评论将减少到一个小数目。这应该根据你的网站去调节,以确保有足够的内容,导致滚动。在下面的例子,建议被限制在3。分页的最大数也取决于评论总数于除以3。一旦最大的评论数已经返回,最大分页数是用来防止进一步的Ajax调用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Globalization;
using System.Data.Entity;
using MvcApplication.Models;
namespace MvcApplication.Controllers
{
public class HomeController : Controller
{
private BookDBContext db = new BookDBContext();
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
// Get our recent comments
var bookcomments = db.BookComments.Include(b => b.Book).OrderByDescending(b => b.Created).Take(3);
var count = db.BookComments.Count();
ViewBag.maxPages = count / 3 + 1;
return View(bookcomments);
}
public ActionResult ChangeLanguage(string language)
{
Session["CurrentLanguage"] = new CultureInfo(language);
return Redirect("Index");
}
public ActionResult About()
{
return View();
}
public ActionResult MobileTest()
{
return View();
}
public ActionResult MobileTest2()
{
return View();
}
}
}

同样的功能需要被复制到一个新的异步controller。控制器文件夹选中,右键单击并选择“添加→控制器。新
控制器将被命名为CommentFeedController。该控制器不需要脚手架模板功能,下拉,选择空
控制器,然后按添加。

这个控制器会看起来与一个典型的控制器稍有不同。使用异步控制器,一个view将分成两个函数。第一个函数执行的异步
请求(例如,检索的view)。第二个函数接收结果,异步调用和返回或显示的结果。

提示:在下面的例子,呈现局部视图。在某些应用中,它可能是有益的,以减少网络流量,返回一个JSON结果,让JavaScript代码处理与显示。但是,要简化这个例子,重点放在异步控制器,前者将用于返回一个partial view。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication.Models;
using System.Data.Entity;
namespace MvcApplication.Controllers
{
public class CommentFeedController : AsyncController
{
private BookDBContext db = new BookDBContext();
public void CommentsAsync(int page)
{
AsyncManager.OutstandingOperations.Increment();
AsyncManager.Sync(() =>
{
var bookcomments = db.BookComments.Include(
b => b.Book).OrderByDescending(b =>
b.Created).Skip(page * 3).Take(3);
AsyncManager.Parameters["bookcomments"] =
bookcomments;
AsyncManager.OutstandingOperations.Decrement();
});
}
public ActionResult CommentsCompleted(
IEnumerable<BookComment> bookcomments)
{
return PartialView(bookcomments);
}
}
}

第一个 函数,CommentsAsync,接收从javascript传入的当前页面,并且用这个值去检索接下来的三个评论。然后通过异步方法,检索评论并且传递一个变量到第二个函数。最终的事是执行AsyncManager.OutstandingOperations.Decrement()方法。OutstandingOperations(未解决操作)的increment(递增)和decrement(递减)的匹配是很重要的。否则,当他们不匹配时,sync manager 将取消请求,这可以组织永不休止的请求。

第二个函数接收book comments 并且返回一个partial view。这和Home/Index view一样。在这个过程的最后一个步骤是创建partial view。右击文件夹,添加新文件夹。这个文件夹应该命名为CommentFeed去匹配controller的名字。选择这个文件夹,右击,点Add→View 命名为Comments-----在添加它之前确定去检查Partial view。

@model IEnumerable<MvcApplication.Models.BookComment>
@foreach (var item in Model) {
<h3><a href="@Url.Action(" rel="external nofollow" Details", "Books", new {ID=item.Book.ID } )">
@Html.DisplayFor(modelItem => item.Book.Title)
</a></h3>
<h4>Comment Posted: @Html.DisplayFor(
modelItem => item.Created)</h4>
<p>@MvcHtmlString.Create(Html.Encode(item.Comment).Replace(
Environment.NewLine, "<br />"))</p>
}

上边的view遍历comments,并首先显示书的标题和详细信息页面的链接,然后创建评论的日期,最后创建comment本身。由于View里可能包含换行符,用<br/>替代每个Evironment.NewLine去匹配评论输入间距。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

jQuery 相关文章推荐
jQuery实现的手风琴侧边菜单效果
Mar 29 jQuery
jQuery列表检索功能实现代码
Jul 17 jQuery
jQuery实现打开网页自动弹出遮罩层或点击弹出遮罩层功能示例
Oct 19 jQuery
jquery.picsign图片标注组件实例详解
Feb 02 jQuery
基于jQuery实现无缝轮播与左右点击效果
May 13 jQuery
jQuery实现轮播图及其原理详解
Apr 12 jQuery
详解jQuery设置内容和属性
Apr 11 jQuery
Jquery 动态添加元素并添加点击事件实现过程解析
Oct 12 jQuery
jQuery实现可编辑的表格
Dec 11 jQuery
jquery选择器和属性对象的操作实例分析
Jan 10 jQuery
JavaScript或jQuery 获取option value值方法解析
May 12 jQuery
ajax jquery实现页面某一个div的刷新效果
Mar 04 jQuery
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
Jun 18 #jQuery
如何使用CSS3和JQuery easing 插件制作绚丽菜单
Jun 18 #jQuery
如何用webpack4.0撸单页/多页脚手架 (jquery, react, vue, typescript)
Jun 18 #jQuery
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
Jun 18 #jQuery
如何使用CSS3+JQuery实现悬浮墙式菜单
Jun 18 #jQuery
jquery中为什么能用$操作
Jun 18 #jQuery
js/jQuery实现全选效果
Jun 17 #jQuery
You might like
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
2010/03/15 PHP
php监测数据是否成功插入到Mysql数据库的方法
2016/11/25 PHP
JavaScript 实现??打印?理
2007/04/28 Javascript
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
JS.elementGetStyle(element, style)应用示例
2013/09/24 Javascript
JS获取键盘上任意按键的值(实例代码)
2013/11/12 Javascript
jQuery实现TAB选项卡切换特效简单演示
2016/03/04 Javascript
如何让一个json文件显示在表格里【实现代码】
2016/05/09 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
url传递的参数值中包含&amp;时,url自动截断问题的解决方法
2016/08/02 Javascript
JavaScript使用Range调色及透明度实例
2016/09/25 Javascript
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
JS实现十字坐标跟随鼠标效果
2017/12/25 Javascript
javascript获取图片的top N主色值方法详解
2018/01/26 Javascript
微信小程序分享功能onShareAppMessage(options)用法分析
2019/04/24 Javascript
详解微信小程序用定时器实现倒计时效果
2019/04/30 Javascript
layUI实现前端分页和后端分页
2019/07/27 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
2019/08/27 Javascript
uni-app 支持多端第三方地图定位的方法
2020/01/03 Javascript
Python设计模式之命令模式简单示例
2018/01/10 Python
利用python为运维人员写一个监控脚本
2018/03/25 Python
Python使用selenium实现网页用户名 密码 验证码自动登录功能
2018/05/16 Python
python实现时间o(1)的最小栈的实例代码
2018/07/23 Python
python 输入一个数n,求n个数求乘或求和的实例
2018/11/13 Python
用Python实现数据的透视表的方法
2018/11/16 Python
python__name__原理及用法详解
2019/11/02 Python
一篇文章搞懂python的转义字符及用法
2020/09/03 Python
基于Python中Remove函数的用法讨论
2020/12/11 Python
html2canvas截图空白问题的解决
2020/03/24 HTML / CSS
Harman Audio官方商店:购买JBL、Harman Kardon、Infinity和AKG
2019/12/05 全球购物
大学生的创业计划书就该这么写
2014/01/30 职场文书
2014年三八妇女节活动总结
2014/03/01 职场文书
2016年三严三实党课学习心得体会
2016/01/06 职场文书
解决jupyter notebook图片显示模糊和保存清晰图片的操作
2021/04/24 Python
python自动化测试之Selenium详解
2022/03/13 Python
python创建字典及相关管理操作
2022/04/13 Python