使用异步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实现火车票买票城市选择切换功能
Sep 15 jQuery
jqueryUI tab标签页代码分享
Oct 09 jQuery
jQuery+ajax实现动态添加表格tr td功能示例
Apr 23 jQuery
jQuery插件Validation表单验证详解
May 26 jQuery
jQuery实现上下滚动公告栏详细代码
Nov 21 jQuery
jQuery实现的老虎机跑动效果示例
Dec 29 jQuery
简单易扩展可控性强的Jquery转盘抽奖程序
Mar 16 jQuery
基于jQuery实现可编辑的表格
Dec 11 jQuery
jquery将信息遍历到界面上实例代码
Jan 21 jQuery
jQuery表单校验插件validator使用方法详解
Feb 18 jQuery
jQuery实现的分页插件完整示例
May 26 jQuery
JQuery绑定事件四种实现方法解析
Dec 02 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
S900/ ETON E1-XM 收音机
2021/03/02 无线电
JAVA/JSP学习系列之六
2006/10/09 PHP
PHP采集腾讯微博的实现代码
2012/01/19 PHP
php 判断数组是几维数组
2013/03/20 PHP
php解析非标准json、非规范json的方式实例
2020/12/10 PHP
js 通用javascript函数库整理
2011/08/14 Javascript
JavaScript给url网址进行encode编码的方法
2015/03/18 Javascript
JS实现仿Windows7风格的网页右键菜单效果代码
2015/09/11 Javascript
js css实现垂直方向自适应的三角提示菜单
2016/06/26 Javascript
Bootstrap轮播插件中图片变形的终极解决方案 使用jqthumb.js
2016/07/10 Javascript
element el-input directive数字进行控制
2018/10/11 Javascript
详解vue几种主动刷新的方法总结
2019/02/19 Javascript
vue基础之事件v-onclick=&quot;函数&quot;用法示例
2019/03/11 Javascript
详解为element-ui的Select和Cascader添加弹层底部操作按钮
2020/02/07 Javascript
vue移动端的左右滑动事件详解
2020/06/17 Javascript
python threading模块操作多线程介绍
2015/04/08 Python
python中defaultdict的用法详解
2017/06/07 Python
python 文件操作删除某行的实例
2017/09/04 Python
对python程序内存泄漏调试的记录
2018/06/11 Python
python一键去抖音视频水印工具
2018/09/14 Python
python处理DICOM并计算三维模型体积
2019/02/26 Python
Python 用三行代码提取PDF表格数据
2019/10/13 Python
Django更新models数据库结构步骤
2020/04/01 Python
python打开文件的方式有哪些
2020/06/29 Python
如何利用python生成MD5并去重
2020/12/07 Python
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
基于html5实现的图片墙效果
2014/10/16 HTML / CSS
HTML5触摸事件演化tap事件介绍
2016/03/25 HTML / CSS
eVitamins日本:在线购买折扣维生素、补品和草药
2019/04/04 全球购物
介绍一下Linux文件的记录形式
2013/09/29 面试题
应用电子技术专业个人求职信
2013/09/21 职场文书
机械绘图员岗位职责
2013/11/19 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
交心谈心活动总结
2015/05/11 职场文书
校长新学期寄语2016
2015/12/04 职场文书
Python机器学习之基础概述
2021/05/19 Python