65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET DataList控件中的无限滚动

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2011年11月30日

CPOL

2分钟阅读

viewsIcon

31775

像 Facebook 新闻源或 Twitter 推文一样的无限滚动

一篇技术博客文章在此处查看完整博客。

无限滚动并不是什么难事,例如Facebook的新闻流或Twitter的推文,当用户到达页面底部时,新闻或推文会更新。实际上,客户端脚本会检查容器的滚动位置,如果位置在底部,脚本会从服务器请求内容并更新容器。在这里,容器是一个DIV标签,命名为holder,并设置了一些样式标签heightwidthoverflow.holder,这些样式位于DataList中。

Holder的CSS样式

<style type="text/css">
    #holder {width: 1900px; height:200px;overflow:auto;  }
</style>

在这里,我使用了Northwind数据库的Products表来演示本文中的无限滚动,并使用了一个Handler页面。 首次加载页面时,DataList中包含10条记录,请看下面的示例:

if (!IsPostBack)
{
    DataClass data = new DataClass();
    DataList1.DataSource = data.FirstTenRecords();
    DataList1.DataBind();
}

并且在客户端,我将当前项目计数设置为10,将下一个项目计数设置为0

var current=10;
var next=0;

然后调用JavaScript中的函数来加载下一个内容,这无非就是通过AJAX调用服务器,即使用一个包含start和next的查询字符串请求Handler页面。 下面的图像显示了客户端的请求URL,我使用了Firebug来显示请求。

让我们看看loadNext

 var loadNext = function () {
            next = current + 10;
            $.ajax({
                url: "Handler.ashx?start=" + current + "&next=" + next,
                success: function (data) {
                    $("#DataList1").append(data);
                }
            });
            current = current + 10;
        };

在调用Handler页面之前设置next,然后在将current设置为current+10之后。

  next = current + 10;
  current = current + 10;

为了从特定的行号获取数据,我使用了一个存储过程,它将返回我的数据。 我想发送位置的数字,如果我发送start=10&next=20,它将从数据库返回第10行到第20行的数据。

USE [Northwind]
GO
/****** Object:  StoredProcedure [dbo].[ProductPages]    
	Script Date: 11/28/2011 12:03:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ProductPages]
(
 @start int,
 @next int
) 
AS
BEGIN
SELECT ProductID,ProductName,UnitPrice FROM
(
   SELECT ROW_NUMBER() OVER(ORDER BY ProductID,ProductName,UnitPrice) NUM,
   * FROM Products
) A 
WHERE NUM >@start AND NUM <=@next
END

现在让我们看看它是如何工作的。 所有的工作都取决于holder的滚动函数。 脚本检查容器的滚动位置是否在底部,如果是,则调用loadNext()函数。

 $(document).ready(function () {
            $("#holder").scroll(function () {
                if ($(this)[0].scrollHeight - 
			$(this).scrollTop() == $(this).outerHeight()) {
                    loadNext();
                }
            });
        });

Handler页面就像一个aspx页面一样简单。 它调用一个类文件DataClassDataClass是一个简单的类文件,用于减少Handler页面中的大量代码。 它调用DataLayer并从数据库返回数据,在进行一些格式化处理后,将其填充到DataList中,并将其写入响应。

public void ProcessRequest(HttpContext context)
    {
        string startQstring = context.Request.QueryString["start"];
        string nextQstring = context.Request.QueryString["next"];
        //null check
        if ((!string.IsNullOrWhiteSpace(startQstring)) && 
		(!string.IsNullOrWhiteSpace(nextQstring)))
        {
            //convert string to int
            int start = Convert.ToInt32(startQstring);
            int next = Convert.ToInt32(nextQstring);
            
            //setting content type
            context.Response.ContentType = "text/plain";
            DataClass data = new DataClass();
            //writing response
            context.Response.Write(data.GetAjaxContent(start, next));
        }
    }

只有一个类文件。 但是我将类放在该文件中。

  1. DataClass
    • Handler页面上包含两个函数,我们正在调用第一个函数GetAjaxContent(start,end),它从数据库返回记录
    • 第二个函数在Page_Load事件中加载数据
  2. 提供
    • web.config提供SqlConnection
  3. DBHelper
    • 数据层请看
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

/// <summary>
/// Summary description for DataClass
/// </summary>
/// 
public class DataClass
{
    public DataClass()
    {
    }
    /// <summary>    
    ///  return rows depend on position
    ///  if you need 10th to 20th you need to pass start=10 and end=20
    /// </summary>
    /// <returns>
    /// database start position of one row
    /// database end position of one row
    /// </returns>
    public string GetAjaxContent(int start, int end)
    {
        string result = string.Empty;
        //adding sp params with values in Dictionary entry.
        Dictionary<string,> keyValPair = new Dictionary<string,object>();
        keyValPair.Add("@start", start);
        keyValPair.Add("@next", end);

        DBHelper DBHelper = new DBHelper();
        //passing the Stored Procedure name and keyvalue pair
        DataTable dataTable = DBHelper.GetTable("ProductPages", keyValPair);
        if (dataTable.Rows.Count > 0)
        {
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                result += string.Format(@"<table>
<tbody>
	<tr>
		<td style="width: 50px; ">{0}</td>
		<td style="width: 400px; ">{1}</td>
		<td style="width: 150px; ">{2}</td>
	</tr>
</tbody>
</table>", dataTable.Rows[i][0].ToString(), dataTable.Rows[i][1].ToString(), 
	dataTable.Rows[i][2].ToString());
            }
        }
        //this string is going to append on Datalist on client.
        return result;
    }
    /// <summary>
    /// function to bind data on page load
    /// </summary>
    /// <returns />
    public DataTable FirstTenRecords()
    {
        Dictionary<string,object> keyValPair = new Dictionary<string,object>();
        keyValPair.Add("@start", 0);
        keyValPair.Add("@next", 10);

        DBHelper DBHelper = new DBHelper();
        DataTable dataTable = DBHelper.GetTable("ProductPages", keyValPair);
        return dataTable;
    }
}

/// <summary>
/// return sqlconnection string from web.config file
/// </summary>
public class Provider
{
    public static SqlConnection GetConnection()
    {
        return new SqlConnection(ConfigurationManager.AppSettings["SqlConnectionString"]);
    }
}
/// <summary>
/// Data layer
/// </summary>
public class DBHelper
{
    public DBHelper()
    { }

    SqlConnection con;
    SqlCommand cmd;
    SqlDataAdapter adapter;
    public DataTable GetTable(string SPName, Dictionary<string,object> SPParamWithValues)
    {
        DataTable dataTable = new DataTable();
        try
        {
            con = Provider.GetConnection();
            //open DB connection
            con.Open();
            cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = con;
            cmd.CommandText = SPName;
            foreach (KeyValuePair<string,object> paramValue in SPParamWithValues)
            {
                cmd.Parameters.AddWithValue(paramValue.Key, paramValue.Value);
            }
            adapter = new SqlDataAdapter(cmd);
            adapter.Fill(dataTable);
        }
        finally
        {
            //close connection string
            con.Close();
        }
        return dataTable;
    }
} 

下载源代码

ASP.NET DataList控件中的无限滚动 - CodeProject - 代码之家
© . All rights reserved.