用Rico LiveGrid小部件创建数据集导航

        从开始构建动态 Web 应用程序起,开发人员一直都是使用传统分页技术。每当需要显示大量的数据时,都要使用分页技术来每次显示一部分数据。用户使用 Next 或 Previous 按钮从一个数据集或页面导航到另一个数据集或页面。

        如今,传统分页技术的一些变体也得到应用。有些是向用户显示 First、Previous、Next 和 Last 按钮,有些是使用数字,还有一些则结合使用按钮和数字。分页的概念可以帮助用户和服务器有效地处理大量的数据。

        然而,最近 Ajax 的盛行却改变了开发人员设计和构建 Web 应用程序的方式。通过使用 Ajax,可以构建外观和行为更接近于传统桌面应用程序的 Web 应用程序。有些开放源码和商业 JavaScript/Ajax 框架和库提供了直接可用的小部件(widget),使得 Ajax 模型更易于实现。开发人员可以使用这些小部件轻松地为 Web 应用程序添加丰富的特性和功能。

        其中一个那样的框架就是 Rico。在本文中,我将简要地介绍这个开放源码的客户端 JavaScript 框架,然后着重描述它的一个小部件,即 LiveGrid。正如本文要演示的那样,可以通过实现 LiveGrid 来替代 Web 应用程序中传统的分页模型。

 

        Rico 库

        Rico 库是一个 JavaScript 文件,可以将这个库包括在任何 Web 页面中,以便使用丰富的特性和小部件。这个库处理很多复杂的实现细节,包括跨浏览器的兼容性,使您得以心无旁骛地创建页面功能。

        Rico 特性或小部件使用起来很简单:只需编写几行代码将那个特性或小部件集成到一个给定页面上。例如,Rico 为将 Ajax 支持添加到 Web 页面中提供了一个非常简单的接口。只需添加 5 到 6 行 JavaScript 代码,就可以将 Ajax 功能添加到 Web 页面中,然后,就可以向服务器发出 Ajax 请求,并处理来自服务器的响应。无需直接与 XmlHttpRequest JavaScript 对象打交道,这一切都可以实现。

        通过 Rico,将拖放之类的可视化效果添加到 Web 页面也很容易。通过 Rico 库,可以将任何 HTML 或 JavaScript 对象定义为 draggable(可拖放的) 或一个 drop zone(拖放区)。这样定义之后,就可以在页面上拖动可拖放对象,并将其放入一个或多个用户定义的拖放区。Rico 自动处理该功能的所有实现细节,所以只需编写几行代码。

        如果使用 Rico,那么添加淡入、动画缩放和位移、旋转等动画效果也是非常简单的。最流行的一个 Rico 小部件就是 Accordion,它显示一组可折叠的抽屉。每个抽屉有一个抽屉标题和一个内容区。单击一个抽屉标题就可以显示那个抽屉的内容,同时也隐藏其他抽屉中的内容。另一个非常流行的小部件是 LiveGrid,本文的后面将着重讲到这个小部件。

 

        一个简单的 LiveGrid

        图 1 中的 LiveGrid 是一个可滚动的信息表,每当用户单击滚动条,表中的数据就动态更新。这个表被连接到一个活动的数据源,对这个表的更新是借助 Ajax 完成的。


图 1. 初始的 LiveGrid
初始的 LiveGrid

        LiveGrid 显示一个可滚动的包含 20 部影片的列表。每当用户单击滚动条,表的内容就随之更新,显示新的一组影片。当需要新的一组数据时,Rico 对服务器发出 Ajax 调用。它使用缓冲技术,以取得更好的性能,并使滚动看上去更为流畅。因此,可能并不是每次单击滚动条都会导致 Ajax 请求。Rico 首先使用缓冲区中的数据来更新网格,当用光了缓冲区中所有的数据时,才发出 Ajax 请求。图 2 显示了用户单击一次滚动条后 LiveGrid 看上去的样子。LiveGrid 还支持列排序。如果网格中实现了排序,那么用户可以单击列名,然后对这个列进行排序。


图 2. 单击滚动条后的 LiveGrid
单击滚动条后的 LiveGrid

        创建一个 LiveGrid

        作为一个学习的例子,我将展示如何创建 Movies LiveGrid above。您需要从 Rico 主页下载 download rico.js 和 prototype.js。注意,Rico 库使用了另一个开放源代码框架 Prototype 中的特性,因此这里需要 prototype.js。此外,还需要一个 Web 应用服务器,用于处理来自 Rico 的 Ajax 调用。对于这个例子,我将使用 Apache Tomcat 6.0。

可以从编写这个例子的客户端代码开始。首先要做的是将 rico.js 和 prototype.js 库包括在页面中。假设这两个库文件与 HTML 文件在同一个目录中,清单 1 展示了如何将这两个库包括在页面中。


清单 1. 从 Rico 和 Prototype 库开始

				
<script src="prototype.js"></script>
<script src="rico.js"></script>

        接下来,添加一个占位符,用于容纳显示图 1 中文本 "Showing 1 - 5 of 20 Movies" 的标签。每当用户单击滚动条,这个标签就会更新。


清单 2. 设置 showLabel

				
<div id="showingLabel" >Showing 1 - 5 of 20 Movies</div>

        然后,添加显示图 1 中列名(例如 Number、Title、Year)的 LiveGrid 标题。


清单 3. 添加 LiveGrid 标题

				
<table cellspacing="0" cellpadding="0" width="400">
    <tr>
        <th bgcolor="#999999" width="30">#</th>
        <th bgcolor="#999999" width="310">Title</th>
        <th bgcolor="#999999" width="60">Year</th>
    </tr>
</table>

        最后,可以创建 Rico 用于显示影片数据的表。用下面代码创建的表有 6 个行,3 个列。表中每隔一行有一个浅灰色背景。要使 LiveGrid 正确运行,需要在表中额外创建一行。因此,如果创建一个要显示 5 个行的 LiveGrid,那么所创建的 HTML 表需要 6 行。如果没有额外的行,那么 LiveGrid 的滚动功能将失常。清单 4 显示了创建 LiveGrid 使用的 HTML 表所需的代码。


清单 4. LiveGrid 数据 HTML 表

				
<div id="movieDiv" style="float:left">
    <table id="movie_grid" cellspacing="0" cellpadding="0" 
        width = "400px" style="border:1px solid #ababab" >
            <tr>
        		<td width="30"> </td>
                <td width="310"> </td>
                <td width="60"> </td>
            </tr>
            <tr>
                <td bgcolor="#eeeeee" width="30"> </td>
                <td bgcolor="#eeeeee"  width="310"> </td>
                <td bgcolor="#eeeeee"  width="60"> </td>
            </tr>
            <tr>
                <td width="30"> </td>
                <td  width="310"> </td>
                <td  width="60"> </td>
            </tr>
            <tr>
                <td bgcolor="#eeeeee" width="30"> </td>
                <td bgcolor="#eeeeee"  width="310"> </td>
            <td bgcolor="#eeeeee"  width="60"> </td>
            </tr>
            <tr>
                <td width="30"> </td>
                <td  width="310"> </td>
                <td  width="60"> </td>
            </tr>
            <tr>
                <td bgcolor="#eeeeee" width="30"> </td>
                <td bgcolor="#eeeeee"  width="310"> </td>
                <td bgcolor="#eeeeee"  width="60"> </td>
            </tr>
    </table>
</div>

  定义 LiveGrid

   设置好表和数据之后,就可以定义用于将清单 4 中的 HTML 表变为 Rico LiveGrid 的 JavaScript 函数。清单 5 中显示的函数名为 loadGrid 函数。

清单 5. 定义 Rico LiveGrid
				
<script>
    function loadGrid() {
        var opts = {   prefetchBuffer: true, onscroll : updateLabel };
        var liveGrid = new Rico.LiveGrid( 'movie_grid',5, 20, 'MovieData', opts); 
    }
</script>

    loadGrid 函数中的第一行指定 LiveGrid 的选项。当把 prefetchBuffer 选项设为 true 时,就是告诉 Rico 在构造 LiveGrid 时取数据。如果将这个选项设为 false,那么 LiveGrid 装载时没有任何数据,直到单击一次滚动条之后才显示数据。

通过使用 onScroll 选项可以定义一个函数,每当用户单击滚动条时,Rico 就调用这个函数。在这个例子中,需要更新显示文本 "Showing 1 - 5 of 20 Movies" 的 label。为此,可以定义一个名为 updateLabel 的 JavaScript 函数,并让 Rico 在用户单击滚动条的时候调用该函数。还可以使用本例中没有使用的 onscrollidle 选项来定义当滚动暂停或停止时调用的 JavaScript 函数。

        另一个有用的选项是 requestParameters,可以使用该选项将额外的参数发送至处理 Ajax 请求的服务。还可以使用 requestParameters 过滤 LiveGrid 中显示的数据。例如,如果只想在 LiveGrid 中显示动作片,那么可以将 requestParameters 设置为 genre=action,处理 Ajax 调用的服务将返回那种类型的影片。

loadGrid 函数中的第二行声明 LiveGrid。构造函数中的第一个参数是被转换成 LiveGrid 的 HTML 表的 ID。在这个例子中,这个 ID 为 "movie_grid"。第二个参数表明要在 LiveGrid 中显示多少行,在这个例子中是 5 行。第三个参数表明 LiveGrid 中的最大行数,在这个例子中为 20。第四个参数应该为负责处理 Ajax 调用的服务器端 script/servlet 的 URL。在这个例子中,我创建了一个名为 MovieData 的 servlet,用于处理来自 Rico 的 Ajax 请求。   

 

      装载和更新网格

        每当装载 HTML 页面时,需要调用 loadGrid 函数。清单 6 显示了这是怎么完成的。


清单 6. 调用 loadGrid

				
<body οnlοad="javascript:loadGrid()">

        最后,定义用于更新 Movie LiveGrid 上的 label 的函数,如清单 7 所示。


清单 7. updateLabel 函数

				
<script>
    function updateLabel( liveGrid, offset ) {
        $('showingLabel').innerHTML = "Showing " + (offset+1) + " - " + 
        (offset+liveGrid.metaData.getPageSize()) + " of " + 
        liveGrid.metaData.getTotalRows() + " movies";
	}
</script>

        每当用户单击滚动条时,就会调用 updateLabel 函数。它主要组合变量和 Rico 库来构造出类似 "Showing 1 - 5 of 20 movies" 的字符串。 如果不熟悉 Prototype JavaScript 框架,可以使用 $(DIVNAME) 语法用与 DIVNAME 匹配的 ID 引用页面上的任何对象。因此,$('showingLabel').innerHTML 相当于 document.getElementById("showingLabel").innerHTML。在这个例子中,每当用户单击滚动条时,便用一个更新的字符串替换 DIV 标记的 innerHTML 值。

设置服务器端

Rico 中的大部分代码编写工作是在客户端进行的,但在服务器端也有一些重要的事情要做。也就是说,需要设置服务器端脚本或 servlet 来处理 Ajax 调用。如前所说,我创建了一个例子 servlet,用于处理来自 Rico 的 Ajax 请求。清单 8 显示为了使 LiveGrid 小部件正常运行,应该如何编写来自 servlet 的 XML 响应。


清单 8. XML 响应所需的格式

				
<?xml version="1.0" encoding="ISO-8859-1"?>
    <ajax-response>
       <response type="object" id='movie_grid_updater'>
            <rows update_ui='true' >
               <tr>
                   <td>1</td>
                   <td>Star Wars</td>
                   <td>1977</td>
               </tr>
               <tr>
                   <td>2</td>
                   <td >The Godfather</td>
                   <td>1972</td>
               </tr>
               ...
            </rows>	
    </response>
</ajax-response>

        注意,response 标记中 id 属性的前两个单词("movie_grid")与之前为 LiveGrid 定义的 HTML 表中的 id 属性是匹配的。为了使 Rico 更新 LiveGrid 中的数据,它们应该匹配。在通常情况下,服务器端脚本或 servlet 连接到数据源,并生成以上格式的 XML。Rico 负责从这个 XML 响应中提取数据,并用新数据填充 LiveGrid。注意要将响应的 content-type 设置为 "text/xml"。如果没有这样做,LiveGrid 将不能工作。XML 版本和编码也必须分别设置为 "1.0" 和 "ISO-8859-1"。可以如清单 9 所示用 Java™ 代码设置 content-type。


清单 9. 设置 Ajax 响应的 content-type

				
response.setHeader("Content-Type", "text/xml");

        4 个数据参数

        现在,您可能对脚本或 servlet 如何知道何时生成什么数据感到困惑。在本文的前面,我提到 Rico 框架使用了缓冲技术,当它需要数据时,它就会请求数据。当 Rico 向后端发出一个 Ajax 请求时,它可能会以 URL 中的查询字符串的形式发送 4 个参数。当提供了这些参数时,后端必须使用这些参数来生成适当的 Ajax 响应。这 4 个参数是:

offset
表明返回的数据集中的第一行数据是什么。举个例子,假设 LiveGrid 一开始装载时 offset 为 0。Rico 在初始装载期间取出 150 行数据,并使用缓冲区存储该数据。在显示完所有 150 行数据之后,它将 offset 值设为 151,并向后端发出一个 Ajax 请求。
page_size
表明 Rico 要后端返回的数据的行数。
sort_col
表明将数据返回到 Rico 之前,按哪个列对数据进行排序。
sort_dir
表明按升序还是降序(ACS 或 DECS)对列进行排序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.OleDb; namespace 保存GRID数据示例 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button2_Click(object sender, EventArgs e) { //提示是否修改 #region//--------修改数据就将数据保存并显示 if (MessageBox.Show("是否保存数据?", "系统消息", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK) { #region ..........这里是保存数据代码 //结束编辑 dataGridView1.EndEdit(); //重新用表格数据填充数据容器 OleDbDataAdapter Ada = new OleDbDataAdapter(); DataTable table = (DataTable)dataGridView1.DataSource; //重新启动连接 String ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Windows.Forms.Application.StartupPath + "/驱动.mdb"; //用Buider方法更新数据 using (OleDbConnection connection = new OleDbConnection(ConnectionString)) { Ada.SelectCommand = new OleDbCommand("SELECT * FROM 表", connection); OleDbCommandBuilder builder = new OleDbCommandBuilder(Ada); Ada.UpdateCommand = builder.GetUpdateCommand(); try { //更新数据表数据时 Ada.Update(table); table.AcceptChanges(); MessageBox.Show("操作已成功!数据将全部被保存......", "系统消息", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2); } catch (System.Data.OleDb.OleDbException ex) { throw new Exception(ex.Message); } } #endregion } #endregion #region //--------不修改就初始化显示以前数据 else { MessageBox.Show("用户取消操作,数据将恢复到初始状态......"); OleDbConnection A = new OleDbConnection(); A.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Windows.Forms.Application.StartupPath + "/驱动.mdb"; try { A.Open(); DataSet B = new DataSet(); string sqlStr = "Select * from 表"; OleDbDataAdapter C = new OleDbDataAdapter(sqlStr, A); C.Fill(B); dataGridView1.DataSource = B.Tables[0]; } catch (System.Data.OleDb.OleDbException ex) { throw new Exception(ex.Message); } finally { A.Close(); } } #endregion } private void button1_Click(object sender, EventArgs e) { OleDbConnection A = new OleDbConnection(); A.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Windows.Forms.Application.StartupPath + "/驱动.mdb"; try { A.Open(); DataSet B = new DataSet(); string sqlStr = "Select * from 表"; OleDbDataAdapter C = new OleDbDataAdapter(sqlStr, A); C.Fill(B); dataGridView1.DataSource = B.Tables[0]; } catch (System.Data.OleDb.OleDbException ex) { throw new Exception(ex.Message); } finally { A.Close(); } } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值