zoukankan      html  css  js  c++  java
  • [翻译]ASP.NET MVC 3 开发的20个秘诀(十七)[20 Recipes for Programming MVC 3]:卷帘式分页加载

    议题

    现在很多网站都与数据库进行交互。如果网站流量很大,使用SQL来检索数据会带来非常大的压力。更重要的是,用户希望在点击链接之后15秒内得到响应的内容,而在页面加载的时,显示之外滚动条下面的内容可能多数内容都是不必要的(滚动条之外没显示的部分)。为了解决这个问题,采取内容“需求点播”方式加载。页面首先会加载足够的内容,当用户在阅读并向下滚动的时候,页面会在不影响用户阅读体验的情况下继续加载更多的内容。

     

    解决方案

    当用户开始滚动网站内容时,使用JQuery将前期加载的内容具体数值传回异步控制器,然后按需加载相关的内容。

     

    讨论

    异步控制器可能是MVC程序集中迄今为止被利用最少的或最不为人所知的控制器,当然也有可能是不知道怎么用它。以下内容是摘抄自MSDN网站的介绍信息:

     

    在可能出现线程不足的应用程序中,您可以配置通过异步方式处理操作。异步请求与同步请求所需的处理时间相同。例如,如果某个请求生成一个需要两秒钟来完成的网络调用,则该请求无论是同步执行还是异步执行都需要两秒钟。但是,在异步调用的过程中,服务器在等待第一个请求完成的过程中不会阻塞对其他请求的响应。因此,当有许多请求调用长时间运行的操作时,异步请求可以防止出现请求排队的情况。

     

    在这个示例中,使用异步请求将是个完美的解决方案,当新用户在发起更为重要的请求时,它将会自动释放IIS资源,因为其中用户的大多数“需求点播”是不太重要的,因为大多数人甚至不会注意到正在加载的额外的内容。

     

    在大多数社交网站中,用户的批注信息更多可能包含的是活动信息。在以前的秘诀中,实现了为书记添加评论的功能。在这个例子中,将会修改页面,列出最近的评论。当用户为了查看更多的评论,他们就会开始滚动,一旦用户开始滚动页面,就发起Ajax请求,请求异步控制器获取剩余部分评论。

     

    首先,修改Home/Index视图,使其显示最近的评论信息。提供书籍最近的相关评论并显示查看书籍基本资料的相关链接。创建新的控制器用来显示评论,这个视图将会调用render方法来显示剩下的信息。

    @model IEnumerable<MvcApplication4.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"
    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减去“Y”坐标最后的位置大于某个具体数字,则通过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 MvcApplication4.Models;
    namespace MvcApplication4.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);
    }
    ...
    }
    }

     

    接下来,需要复制一个新的异步控制器。选中Controllers文件夹,右键单击选择“添加”→“控制器”,将新控制器命名为“CommentFeedController”。这个控制器不需要设置基架选项以及其他内容,直接点击“添加”即可。(译者注:然后将新创建的控制器类的父类改为“AsyncController

     

    这个控制器与之前的默认控制器看起来会有一些区别。异步控制器,每个视图都会有两个方法。第一个方法是用来实现异步请求(例如,获取评论信息)。第二个方法,是在异步调用时返回或显示接收到的结果。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MvcApplication4.Models;
    using System.Data.Entity;

    namespace MvcApplication4.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传回的当前的页码,使用这个值来检索接下来的3条评论。首先是调用OutstandingOperations来通知未完成的请求挂起。然后再将检索评论的代码作为一个方法变量执行第二步操作,最后,再从未完成的计数器中将执行方法减去。在这里最重要的是递增和递减在计数器中的匹配,当递增和递减计数器相同的一段时间后,同步管理器将取消请求,否则,请求永远无法结束。

     

    第二个方法,接收书籍的评论信息,并返回一个分部视图结果。这是一个与Home/Index视图相同的分部视图。在这里最后一步就是创建这个分部视图。右键单击“Views”文件夹,选择“添加”→“新建文件夹”,并将文件夹命名为“CommentFeed”,然后右键单击此文件夹,选择“添加”→“视图”,将其命名为“Comments”,然后确保选中创建视图对话框中的“创建分部视图”选项,然后点击“添加”。

     

    @model IEnumerable<MvcApplication4.Models.BookComment>
    @foreach (var item in Model) {
    <h3><a href="@Url.Action("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>

    }

     

    如上所示,首先将评论按照创建时间排序循环取出,显示书籍标题以及详情链接,评论的创建日期以及最后的评论文本。因为评论中有可能会包含换行符,将其中换行符替换为“<br />”标记。

     

     

    参考

    Asynchronous Controllers 原书地址 书籍源代码

  • 相关阅读:
    《大话数据结构》第1章 数据结构绪论 1.2 你数据结构怎么学的?
    伍迷七八月新浪微博集锦
    《大话数据结构》第9章 排序 9.7 堆排序(下)
    《大话数据结构》第3章 线性表 3.8.2 单链表的删除
    《大话数据结构》第9章 排序 9.5 直接插入排序
    《大话数据结构》第9章 排序 9.8 归并排序(上)
    《大话数据结构》第2章 算法基础 2.9 算法的时间复杂度
    《大话数据结构》第1章 数据结构绪论 1.1 开场白
    《大话数据结构》第9章 排序 9.1 开场白
    [AWS] Assign a public IP address to an EC2 instance after launched
  • 原文地址:https://www.cnblogs.com/o2ds/p/2301660.html
Copyright © 2011-2022 走看看