使用異步controller與jQuery實(shí)現(xiàn)卷簾式分頁
問題
今天很多網(wǎng)站與數(shù)據(jù)庫交互。如果您的網(wǎng)站接收大量的流量,SQL查詢來檢索數(shù)據(jù),是相當(dāng)激烈的。更重要的是因?yàn)槠胀ㄓ脩酎c(diǎn)擊一個(gè)在15秒內(nèi)到達(dá)您的網(wǎng)站的鏈接, 檢索和生成內(nèi)容的工作可能是不必要的,尤其是當(dāng)內(nèi)容是“地域折疊”(不滾動(dòng)是不可見的)。為了幫助解決這個(gè)問題,內(nèi)容將被“按需”載入。足夠的內(nèi)容將被載入,使頁面感覺起來是隨用戶向下滾動(dòng)閱讀遞增的,更多的內(nèi)容將在不影響用戶體驗(yàn)的場(chǎng)景下填充。
解決方案
使用異步controller與jQuery按需加載內(nèi)容,當(dāng)用戶開始通過網(wǎng)站的內(nèi)容滾動(dòng)時(shí)進(jìn)一步加載內(nèi)容。
討論
異步controller可能在許多MVC應(yīng)用中未充分利用。最有可能的是因?yàn)槿藗儾恢浪麄?,更重要的是,不知道何時(shí)使用它們。以下是摘錄見MSDN網(wǎng)站:
“在應(yīng)用中,線程饑餓可能會(huì)發(fā)生,您可以配置action 異步處理。異步請(qǐng)求和同步請(qǐng)求過程需要相同的時(shí)間例如,如果一個(gè)請(qǐng)求,使得網(wǎng)絡(luò)調(diào)用需要兩秒鐘來完成的,請(qǐng)求需要兩秒鐘,無論是執(zhí)行同步或異步。然而,在一個(gè)異步調(diào)用,當(dāng)服務(wù)器響應(yīng)等待它的第一次請(qǐng)求時(shí)完成時(shí)他響應(yīng)其他的請(qǐng)求沒有被阻塞。因此,當(dāng)有許多請(qǐng)求調(diào)用長時(shí)間運(yùn)行的操作時(shí),異步請(qǐng)求會(huì)防止請(qǐng)求排隊(duì)?!?/p>
在這個(gè)例子里,異步請(qǐng)求是完美的解決方案。因?yàn)樗麜?huì)讓IIS服務(wù)器有能力去處理更多重要的請(qǐng)求,比如一個(gè)新的用戶第一次訪問網(wǎng)站。其中,加載用戶點(diǎn)播內(nèi)容是不太重要,因?yàn)榇蠖鄶?shù)人甚至不關(guān)注被加載額外的內(nèi)容。在一個(gè)典型的社交網(wǎng)站,大多數(shù)活動(dòng)可能包含用戶的意見。在以前的秘方中,創(chuàng)建了一個(gè)評(píng)論的功能。
在這個(gè)例子中,將更新網(wǎng)站的網(wǎng)頁,列出最近的評(píng)論。足夠的評(píng)論會(huì)被顯示,所以會(huì)出現(xiàn)滾動(dòng)條。一旦用戶開始滾動(dòng),一個(gè)Ajax請(qǐng)求異步controller將檢索其他評(píng)論。
首先Home/Index view 需要更新去顯示最近的評(píng)論。為了提供一些評(píng)論的上下文內(nèi)容,關(guān)于書的基礎(chǔ)詳情也將被顯示為導(dǎo)航到圖書的鏈接。所以這個(gè)view將簡單的調(diào)用view 中的render function會(huì)在下邊創(chuàng)建:
@model IEnumerable<MvcApplication.Models.BookComment> @{ ViewBag.Title = "Home Page"; } <h2>@ViewBag.Message</h2> <p> To learn more about ASP.NET MVC visit <a 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>
在上面的例子,執(zhí)行滾動(dòng)窗口時(shí)也有一些比較復(fù)雜的JavaScript代碼會(huì)執(zhí)行。一些全局JavaScript變量被定義去保持監(jiān)控當(dāng)前的“Y”滾動(dòng)的位置,最后的“Y”滾動(dòng)位置和當(dāng)前被檢索的頁面。當(dāng)窗口的scrollTop位置減去最后的滾動(dòng)位置是大于一個(gè)具體的數(shù)字,通過Ajax檢索新書評(píng)論并附加到評(píng)論列表。
你將根據(jù)你自己的網(wǎng)站去根據(jù)矯正那個(gè)具體的數(shù)字,基于內(nèi)容的高度,要確保新的內(nèi)容總是要提前檢索。
下一步,HomeController需要更新檢索圖書評(píng)論列表。 評(píng)論在降序排序,以確保最新的創(chuàng)建日期評(píng)論首先顯示。為了防止激烈的數(shù)據(jù)庫負(fù)載,全部評(píng)論將減少到一個(gè)小數(shù)目。這應(yīng)該根據(jù)你的網(wǎng)站去調(diào)節(jié),以確保有足夠的內(nèi)容,導(dǎo)致滾動(dòng)。在下面的例子,建議被限制在3。分頁的最大數(shù)也取決于評(píng)論總數(shù)于除以3。一旦最大的評(píng)論數(shù)已經(jīng)返回,最大分頁數(shù)是用來防止進(jìn)一步的Ajax調(diào)用。
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(); } } }
同樣的功能需要被復(fù)制到一個(gè)新的異步controller??刂破魑募A選中,右鍵單擊并選擇“添加→控制器。新
控制器將被命名為CommentFeedController。該控制器不需要腳手架模板功能,下拉,選擇空
控制器,然后按添加。
這個(gè)控制器會(huì)看起來與一個(gè)典型的控制器稍有不同。使用異步控制器,一個(gè)view將分成兩個(gè)函數(shù)。第一個(gè)函數(shù)執(zhí)行的異步
請(qǐng)求(例如,檢索的view)。第二個(gè)函數(shù)接收結(jié)果,異步調(diào)用和返回或顯示的結(jié)果。
提示:在下面的例子,呈現(xiàn)局部視圖。在某些應(yīng)用中,它可能是有益的,以減少網(wǎng)絡(luò)流量,返回一個(gè)JSON結(jié)果,讓JavaScript代碼處理與顯示。但是,要簡化這個(gè)例子,重點(diǎn)放在異步控制器,前者將用于返回一個(gè)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); } } }
第一個(gè) 函數(shù),CommentsAsync,接收從javascript傳入的當(dāng)前頁面,并且用這個(gè)值去檢索接下來的三個(gè)評(píng)論。然后通過異步方法,檢索評(píng)論并且傳遞一個(gè)變量到第二個(gè)函數(shù)。最終的事是執(zhí)行AsyncManager.OutstandingOperations.Decrement()方法。OutstandingOperations(未解決操作)的increment(遞增)和decrement(遞減)的匹配是很重要的。否則,當(dāng)他們不匹配時(shí),sync manager 將取消請(qǐng)求,這可以組織永不休止的請(qǐng)求。
第二個(gè)函數(shù)接收book comments 并且返回一個(gè)partial view。這和Home/Index view一樣。在這個(gè)過程的最后一個(gè)步驟是創(chuàng)建partial view。右擊文件夾,添加新文件夾。這個(gè)文件夾應(yīng)該命名為CommentFeed去匹配controller的名字。選擇這個(gè)文件夾,右擊,點(diǎn)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,并首先顯示書的標(biāo)題和詳細(xì)信息頁面的鏈接,然后創(chuàng)建評(píng)論的日期,最后創(chuàng)建comment本身。由于View里可能包含換行符,用<br/>替代每個(gè)Evironment.NewLine去匹配評(píng)論輸入間距。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
z-blog SyntaxHighlighter 長代碼無法換行解決辦法(jquery)
由于我的博客主要是代碼分享,很多貼的代碼,都很長。很多時(shí)候我都是手動(dòng)給他換行。但是今天實(shí)在是受不了。從網(wǎng)上找個(gè)辦法解決一下2014-11-11基于jQuery實(shí)現(xiàn)的百度導(dǎo)航li拖放排列效果,即時(shí)更新數(shù)據(jù)庫
基于jQuery實(shí)現(xiàn)的百度導(dǎo)航li拖放排列效果,即時(shí)更新數(shù)據(jù)庫,需要的朋友可以參考下2012-07-07