使用异步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+pjax简单示例汇总
Apr 21 jQuery
jquery实现图片轮播器
May 23 jQuery
jQuery查找和过滤_动力节点节点Java学院整理
Jul 04 jQuery
jQuery实现的粘性滚动导航栏效果实例【附源码下载】
Oct 19 jQuery
jquery 动态遍历select 赋值的实例
Sep 12 jQuery
jquery获取img的src值实例介绍
Jan 16 jQuery
jQuery中each和js中forEach的区别分析
Feb 27 jQuery
jquery实现动态创建form并提交的方法示例
May 27 jQuery
jQuery zTree插件快速实现目录树
Aug 16 jQuery
jquery中attr、prop、data区别与用法分析
Sep 25 jQuery
详解jQuery中的prop()使用方法
Jan 05 jQuery
jquery选择器和属性对象的操作实例分析
Jan 10 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
PHP计算一年多少个星期和每周的开始和结束日期
2014/07/01 PHP
php中类和对象:静态属性、静态方法
2017/04/09 PHP
PHP常用正则表达式精选(推荐)
2019/05/28 PHP
javascript 限制输入和粘贴(IE,firefox测试通过)
2008/11/14 Javascript
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
jQuery autocomplate 自扩展插件、自动完成示例代码
2011/03/28 Javascript
Tab页界面 用jQuery及Ajax技术实现(php后台)
2011/10/12 Javascript
JS判定是否原生方法
2013/07/22 Javascript
JS调用CS里的带参方法实例
2013/08/01 Javascript
JQuery判断checkbox是否选中及其它复选框操作方法合集
2015/06/01 Javascript
简介JavaScript中的getUTCFullYear()方法的使用
2015/06/10 Javascript
jquery实现的仿天猫侧导航tab切换效果
2015/08/24 Javascript
跟我学习javascript的基本类型和引用类型
2015/11/16 Javascript
微信小程序 网络API Websocket详解
2016/11/09 Javascript
详解使用grunt完成requirejs的合并压缩和js文件的版本控制
2017/03/02 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
2017/07/14 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
2018/05/13 Javascript
uni app仿微信顶部导航条功能
2019/09/17 Javascript
JS数据类型STRING使用实例解析
2019/12/18 Javascript
浅谈Vue.use到底是什么鬼
2020/01/21 Javascript
解决vue net :ERR_CONNECTION_REFUSED报错问题
2020/08/13 Javascript
python中list循环语句用法实例
2014/11/10 Python
详解Python中open()函数指定文件打开方式的用法
2016/06/04 Python
python读写LMDB文件的方法
2018/07/02 Python
python实现汉诺塔算法
2021/03/01 Python
Python3实现从排序数组中删除重复项算法分析
2019/04/03 Python
详解Python 字符串相似性的几种度量方法
2019/08/29 Python
Python pip 常用命令汇总
2020/10/19 Python
Pyside2中嵌入Matplotlib的绘图的实现
2021/02/22 Python
印度尼西亚值得信赖的第一家网店:Bhinneka
2018/07/16 全球购物
Linux管理员面试题 Linux admin interview questions
2016/07/08 面试题
运动会广播稿30字
2014/01/21 职场文书
井冈山红色之旅心得体会
2014/10/07 职场文书
三潭印月的导游词
2015/02/12 职场文书
商标侵权律师函
2015/05/27 职场文书
JS实现九宫格拼图游戏
2022/06/28 Javascript