Adobe Spry 中文文档库 使用Spry XML数据集(中)

Working with Spry XML Data Sets

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页面中链接这些文件。

  1. Adobe Labs站点找到Spry ZIP包。
  2. 下载并解压到你的硬盘。
  3. 打开解压后的目录,并找到includes目录,这个目录包含了Spry框架在运行时所必备的xpath.js和SpryData.js文件。
  4. 复制includes目录到你的网站根目录。
  5. 链界Spry相关库文件到你的页面head标记中:
    <script type="text/javascript" src="includes/xpath.js"></script>
    <script type="text/javascript" src="includes/SpryData.js"></script>

    SpryData.js依赖于xpath.js文件,所以要先引用xpath.js文件。

    引用完这些库文件后就可以创建Spry数据集了。

  6. 在HTML标记中添加Spry名字空间声明,如下:
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:spry="http://ns.adobe.com/spry/">

    为了让代码有效,必须声明Spry名字空间。

    注意:在上传链接了Spry特性的页面时,一定要将xpath.js和SpryData.js一并上传。

创建一个Spry XML数据集

  1. 打开一个新的或已存在的HTML页。
  2. 确定你已经链接了Spry库文件到页面中,并声明了Spry名字空间。
  3. 定位数据集的XML源。

    例如,你的XML文件叫cafetownsend.xml,该文件存放在站点根目录下的data目录中:

    data/cafetownsend.xml

    你也可以指定一个XML文件的URL:

    http://www.somesite.com/somefolder/cafetownsend.xml

    注意:决定使用URL或者是相对路径,这取决于你的浏览器的安全模型。
  4. 在你创建数据集前,请确认你已经明白了XML的结构,因为你需要为数据集指定重复的XML节点。

    下例中,cafetownsend.xml文件中包含specials父节点,改接点下有重复的menu_item子节点。

    <?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>
     </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>
     </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>
     </menu_item>
    </specials>
  5. 在引用库文件的script标记后插入下列script块来创建数据集:
    <script type="text/javascript">
     var datasetName = new Spry.Data.XMLDataSet("XMLsource", "XPathToRepeatingChildNode");
    </script>

    在Cafe Townsend范例中,你使用下列语句创建数据集:

    var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item");

    该语句创建了dsSpecials数据集来接受指定XML文件中specials/menu_item节点的数据。数据集为每一个菜单项目都创建了一个列,包括:@id, item, description, 和 price,如下:

    @id

    item

    description

    price

    1

    Summer salad

    organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette.

    7

    2

    Thai Noodle Salad

    lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions.

    8

    3

    Grilled Pacific Salmon

    served with new potatoes, diced beets, Italian parlsey, and lemon zest.

    16

    你也可以指定一个XML数据的URL:

    var dsSpecials = new Spry.Data.XMLDataSet("http://www.somesite.com/somefolder/cafetownsend.xml", "specials/menu_item");
    完成后的范例代码如下:
    <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>
  6. (这步可选) 如果你想对数据排序,你可能会希望把包含数字的列设置为数字类型。

    在创建数据集,可以通过添加setColumnType数据集合方法来设置列类型,下面红色部分:

    <script type="text/javascript"> 
     var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item");  
     dsSpecials.setColumnType("price", "number");
    </script>

    例子中,表达式为dsSpecials数据集的setColumnType方法,该方法有2个参数:一个是要设置数据类型的列名 ("price"),一个是数据类型名 ("number")。

在创建完数据集后,就可以创建动态区域来显示数据了。

创建Spry动态区域并显示数据

创建了Spry数据集后就可以将动态区域绑定到记录集,一个Spry动态区域是页面上的一个区域,可以显示数据并当数据几改变时自动更新。

  1. 确定你已经在页面中链界了Spry库,声明了Spry名字空间并创建了一个数据集。
  2. 给一个包含区域标记添加spry:region属性,该属性语法为spry:region="数据集名字". 注意:除了个别HTML元素外,大多数HTML元素都可以用于动态区域。

    例如,用div标记来显示dsSpecials数据集,给div标记添加spry:region属性,如下:

    <div id="Specials_DIV" spry:region="dsSpecials"></div>
    注意:动态区域可以依赖于多个数据集。给区域添加多个数据集,可以在spry:region属性的值中添加多个数据集名字,名字之见用空格分开,例如:spry:region="dsSpecials dsSpecials2 dsSpecials3".
  3. 在标记内部包含动态区域。你可以用任意HTML元素来显示数据。下面是一个两行的表,第一行包含静态的表头,第二行包含动态数据:
    <table id="Specials_Table"> 
     <tr>  
      <th>Item</th> 
      <th>Description</th> 
      <th>Price</th> 
     </tr>  
     <tr spry:repeat="dsSpecials"> 
      <td>{item}</td>
      <td>{description}</td>
      <td>{price}</td>
     </tr>
    </table>

    单元格里的值参考到数据集中的列。

    注意:如果区域依赖于多个数据集,则引用数据集中的列时需要指定列是哪个数据集的,语法为:{datasetName::columnName}.例如,绑定了2、3个不同的数据集,上面的例子就要写作:{dsSpecials::item}, {dsSpecials::description}, 依次类推.
  4. 给HTML元素添加spry:repea属性,则循环显示数据集中的数据,语法如下:
    spry:repeat="datasetName"

    例子中,你添加了spry:repeat属性到表行标记中,下列红色部分:

    <tr spry:repeat="dsSpecials">
     <td>{item}</td>
     <td>{description}</td> 
     <td>{price}</td>
    </tr>

    例子中,完整的动态区域绑定代码如下:

    <div id="Specials_DIV" spry:region="dsSpecials">
     <table id="Specials_Table">
      <tr> 
       <th>Item</th> 
       <th>Description</th>
       <th>Price</th>  </tr>
      <tr spry:repeat="dsSpecials">
       <td>{item}</td>
       <td>{description}</td> 
       <td>{price}</td>
      </tr>
     </table>
    </div>
  5. 你可以为动态区域定义click事件,允许用户排序数据。
原文地址:https://www.cnblogs.com/booolee/p/772246.html