Spry主要和明细区域概要和结构
使用Spry数据集,你可以创建主要和明细动态区域去显示详细数据,一个区域(主要)控制另一个区域(明细)的数据显示。

- A.
- Master Region (主要区域)
- B.
- Detail Region (明细区域)
通常,主区域会显示指定记录的摘要信息,而明细区域显示指定记录的详细信息。明细区域随主区域的选择变化而变化。
这部分讲述关联于相同数据集的主要区域和明细区域的关系。
在下面的范例中,主要区域显示dsSpecials数据集的数据,明细区域根据主要区域的选择来显示详细数据:
<head> . . . <script type="text/javascript" src="../includes/xpath.js"></script> <script type="text/javascript" src="../includes/SpryData.js"></script> <script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); </script> </head> . . . <body> <!--Create a master dynamic region--> <div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <!--User clicks to reset the current row in the data set--> <tr spry:repeat="dsSpecials" spry:setrow="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> <!--Create the detail dynamic region--> <div id="Specials_Detail_DIV" spry:detailregion="dsSpecials"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> <th>Calories</th> </tr> <tr> <td>{ingredients}</td> <td>{calories}</td> </tr> </table> </div> . . . </body>
在这个范例中,第一个div标记包含id和spry:region两个属性,用于创建包含主要区域的容器:
<div id="Specials_DIV" spry:region="dsSpecials">
主要区域的第2个行标记包含了一个spry:setrow属性,用于设置数据集的当前行。
<tr spry:repeat="dsSpecials" spry:setrow="dsSpecials">
第2个div标记包含spry:detailregion属性以创建一个明细动态区域:
<div id="Specials_Detail_DIV" spry:detailregion="dsSpecials">
每个Spry数据集都保持一个当前行,默认情况下,当前行是数据集的第一行。一个spry:detailregion的工作方式除了在数据集的当前记录改变时更新外都与spry:region相同。
当浏览器页面装载时,明细区域中的表达式 ({ingredients} 和 {calories})将显示数据集中当前行的数据。当用户点击主要区域中的一行时,spry:setrow属性改变数据集中的当前行为用户指定。
{ds_RowID}数据参考是Spry框架为数据集每行自动产生的一个ID,当用户在主要区域指定一个行时,spry:setrow属性将指定的唯一ID提供给setCurrentRow方法,并将其设置为当前行。
当数据集变化后,绑定到该数据集的所有动态区域都将重新生成并显示更新后的数据。因为明细区域类似主要区域都是做为dsSpecials数据集的一个侦听器,同样会在数据变化后更新,并显示用户所指定(新的当前行)的行。

spry:region 和 spry:detailregion 的不同在于 spry:detailregion 响应数据集的CurrentRowChanged事件, 并在事件发生时更新自己。通常spry:regions忽略CurrentRowChange事件,仅在数据集的DataChanged 事件中更新。

Spry 高级主要和明细区域概要和结构
在一些情况下,你可能希望创建包括多个数据集的主/细关系。例如,你有包含众多关联信息的菜单列表,因为带宽的问提,对于用户没有使用到的菜单关联信息没有必要全部获取,仅下载用户请求的详细数据以获得较高的效率,这是AJAX应用中减少数据交换量的常用技术。
下面范例XML源码文件叫cafetownsend.xml:
<?xml version="1.0" encoding="UTF-8"?> <specials> <menu_item id="1"> <item>Summer Salad</item> <description>organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette.</description> <price>7</price> <url>summersalad.xml</url> </menu_item> <menu_item id="2"> <item>Thai Noodle Salad</item> <description>lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions.</description> <price>8</price> <url>thainoodles.xml</url> </menu_item> <menu_item id="3"> <item>Grilled Pacific Salmon</item> <description>served with new potatoes, diced beets, Italian parlsey, and lemon zest.</description> <price>16</price> <url>salmon.xml</url> </menu_item> </specials>
cafetownsend.xml 文件为主要数据集提供数据,每一个菜单项的url节点指向一个唯一的XML文件。每个XML文件中包含了一个对应于菜单项的配方列表,用summersalad.xml做为例子 for example, might look as follows:
<?xml version="1.0" encoding="UTF-8" ?> <item> <item_name>Summer salad</item_name> <ingredients> <ingredient> <name>butter lettuce</name> </ingredient> <ingredient> <name>Macintosh apples</name> </ingredient> <ingredient> <name>Blood oranges</name> </ingredient> <ingredient> <name>Gorgonzola cheese</name> </ingredient> <ingredient> <name>raspberries</name> </ingredient> <ingredient> <name>Extra virgin olive oil</name> </ingredient> <ingredient> <name>balsamic vinegar</name> </ingredient> <ingredient> <name>sugar</name> </ingredient> <ingredient> <name>salt</name> </ingredient> <ingredient> <name>pepper</name> </ingredient> <ingredient> <name>parsley</name> </ingredient> <ingredient> <name>basil</name> </ingredient> </ingredients> </item>
你可以使用你熟悉的XML结构来编写数据,并创建两个数据集在主要/详细区域中显示数据。下列范例中,主要动态区域显示dsSpecials数据集,明细动态区从dsIngredients数据集获取数据:
<head> . . . <script type="text/javascript" src="../includes/xpath.js"></script> <script type="text/javascript" src="../includes/SpryData.js"></script> <script type="text/javascript"> <!--Create two separate data sets--> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); var dsIngredients = new Spry.Data.XMLDataSet("data/{dsSpecials::url}", "item/ingredients/ingredient"); </script> </head> . . . <body> <!--Create a master dynamic region--> <div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <!--User clicks to reset the current row in the data set--> <tr spry:repeat="dsSpecials" spry:setrow="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> <!--Create the detail dynamic region--> <div id="Specials_Detail_DIV" spry:region="dsIngredients"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> </tr> <tr spry:repeat="dsIngredients"> <td>{name}</td> </tr> </table> </div> . . . </body>
在范例中,3个代码块中包含并创建了两个数据集dsSpecials和dsIngredients:
var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); var dsIngredients = new Spry.Data.XMLDataSet("data/{dsSpecials::url}", "item/ingredients/ingredient");
B数据集dsIngredients的URL包含了的{dsSpecials::url}引用第一个数据集的数据。它引用了dsSpecials数据集中的url列,如果URL或XPath包含参考了另一个数据集,那么这个数据集将自动成为所参考的数据集的侦听器,B数据集将以依赖A数据集,每当A数据集数据或当前行发生改变,B数据集都将重新装载。
下面的图例展示了数据集和主要、详细区之间的侦听关系:

在这个范例中,改变dsSpecials数据集的当前行时会发送一个消息给dsIngredients数据集使其改变,因为dsSpecials数据集的每行url列中包含一个不同的URL,dsIngredients数据集必须根据选择的行的URL进行更新。
默认,dsIngredients数据集是通过构造函数里的URL参数指定数据来源的,这里引用的是dsSpecials数据集里的url列。dsSpecials数据集的默认当前行(第一行)包含了一个路径指向summersalad.xml文件,当浏览器装载时详细区域显示该信息。当dsSpecials数据集当前行改变,假如URL改变为salmon.xml,则dsIngredients数据集(以及想关联的详细动态区域)将做相应的更新。
如上图所示,数据集B侦听A数据集的数据和行改变的消息。
范例代码中的详细区域标记spry:region被spry:detailregion替代.spry:region 和 spry:detailregion的区别是spry:detailregion侦听数据集的CurrentRowChange消息(还有DataChanged消息), 在接到消息后更新自己。因为dsIngredients从来不改变(其根据dsSpecials数据集的当前行而改变),所以dsSpecials不需要spry:detailregion属性。在这里spry:region属性定义的区域仅仅侦听DataChanged消息。
容易改造
使用Spry技术改造下面的代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:spry="http://ns.adobe.com/spry"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Hijax Demo - Notes 1</title> </head> <body> <a href="notes1.html">Note 1</a> <a href="notes2.html">Note 2</a> <a href="notes3.html">Note 3</a> <div> <p>This is some <b>static content</b> for note 1.</p> </div> </body> </html>
通过Spry技术,不需要将页面整体装载,你先编写为每一个连接编写页面片段,例如:
<?xml version="1.0" encoding="iso-8859-1"?> <notes> <note><![CDATA[<p>This is some <b>dynamic content</b> for note 1.</p>]]></note> <note><![CDATA[<p>This is some <b>dynamic content</b> for note 2.</p>]]></note> <note><![CDATA[<p>This is some <b>dynamic content</b> for note 3.</p>]]></note> </notes>
改造后的代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:spry="http://ns.adobe.com/spry"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Hijax Demo - Notes 1</title> <script language="JavaScript" type="text/javascript" src="includes/xpath.js"></script> <script language="JavaScript" type="text/javascript" src="includes/SpryData.js"></script> <script language="JavaScript" type="text/javascript"> <!-- var dsNotes = new Spry.Data.XMLDataSet('data/notes.xml', "/notes/note"); --> </script> </head> <body> <a href="note1.html" onclick="dsNotes.setCurrentRowNumber(0); return false;">Note 1</a> <a href="note2.html" onclick="dsNotes.setCurrentRowNumber(1); return false;">Note 2</a> <a href="note3.html" onclick="dsNotes.setCurrentRowNumber(2); return false;">Note 3</a> <div spry:detailregion="dsNotes" spry:content="{note}"> <p>This is some <b>static content</b> for note 1.</p> </div> </body> </html>
附加在前面的代码看起来非常熟悉,但需要注意的是div块包含了一个spry:detailregion属性和spry:content属性。spry:content属性告诉Spry动态区域用该属性指定的参考数据去替换静态数据。
运行这个范例要求你的浏览器启用javascript功能。
运行后,点链接将会使动态区域的内容更新。
在前面的例子,使用用onclick属性快速绑定了链接的Javascript事件句柄。
使用Spry创建动态页面
准备文件
在创建Spry数据集前,先准备一些必要的文件(xpath.js和SpryData.js),xpath.js允许你在创建数据集时指定复杂的XPath表达式,SpryData.js文件包含Spry数据操作库。
在HTML页面中链接这些文件。
创建一个Spry XML数据集
在创建完数据集后,就可以创建动态区域来显示数据了。
创建Spry动态区域并显示数据
创建了Spry数据集后就可以将动态区域绑定到记录集,一个Spry动态区域是页面上的一个区域,可以显示数据并当数据几改变时自动更新。