当你使用Repeater组件时,你所做的就是创建一个MXML容器,此容器为数据源的每个记录重复它的内容。如果你有些弱智,不理解我所说的,那么几分钟之后你就完全理解了。但是在你开始之前,你需要做点铺垫工作。
1.关掉以前的所有文档。我们要用个新的。
2.创建一个新的Flex项目,命名为Chapter8_project。你也可以使用默认的MXML程序名(跟项目名一样)。
你使用Model标签来创建一些短的数据。我们在第六章讨论过Model标签。此处回顾一下,它建立一个典型的XML结构,主要用作测试目的。你通常在其内部放几条记录用来测试。俺在第六章已经说过,它是极少数MXML标签的另类,因为它没有相应的ActionScript类文件。
3.在开始的Application标签下建立如下Model标签:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Model >
<books>
<bookName>The Essential Guide to Dreamweaver CS3</bookName>
<bookName>Foundation Flex for Developers: Data-Driven Applications</bookName>
<bookName>Flash CS3 for Designers</bookName>
</books>
</mx:Model>
</mx:Application>
回想一下第六章关于XML的讨论,Flex将XML数据转换成ArrayCollection类型。尽管你在本例中使用了Model标签,但你在其内部创建了一个XML结构来组织数据。因此你需要将这些数据转换成一个ArrayCollection。
我再说一次,我们可以用MXML来表示ActionScript过程,我们在第六章说过。
4.在你刚创建的Model标签结构下添加如下标签:
<mx:ArrayCollection source="{bookData.bookName}"/>
本例中的source是重复的节点,也就是Model标签bookData的bookName。因为Model标签将它的内容转换成一个MXML结构,所以你根本不需要关心root,也就是books。此外,必须要用大括号来绑定数据。
现在Model结构被转换成一个ArrayCollection,你准备使用Repeater组件了。
5.使用ArrayCollection创建一个Repeater,名为bookArray,作为dataProvider。你给此Repeater组件一个id,叫做bookRepeater。将它放在刚才定义的ArrayCollection下面:
<mx:ArrayCollection source="{bookData.bookName}"/>
<mx:Repeater dataProvider="{bookArray}">
</mx:Repeater>
一旦你建立这个Repeater组件,你所做的就是决定在这个容器中放什么。让我们看个简单的例子。
6.在Repeater结构中,添加一个Label控制器,将它的text属性值设置为Place Book Title Here。
<mx:Repeater dataProvider="{bookArray}">
<mx:Label text="Place Book Title Here"/>
</mx:Repeater>
最后需要做的事情就是检查Application标签的layout属性。如果设置为absolute,你就需要自己设置位置。但如果改为vertical,这个练习就很简单了。
你的最终代码如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Model >
<books>
<bookName>The Essential Guide to Dreamweaver CS3</bookName>
<bookName>Foundation Flex for Developers: Data-Driven Applications</bookName>
<bookName>Flash CS3 for Designers</bookName>
</books>
</mx:Model>
<mx:ArrayCollection source="{bookData.bookName}"/>
<mx:Repeater dataProvider="{bookArray}">
<mx:Label text="Place Book Title Here"/>
</mx:Repeater>
</mx:Application>
7.运行代码。结果如图8-1。
图8-1.Repeater组件
你可以看到Label控制器在Repeater容器中,为每条记录重复一次。本例中,重复了三次。
8.现在你要更进一步,添加一个Button控制器,label属性设置为Add to Cart。将之放在Repeater容器中,就在Label控制器的下面。
<mx:ArrayCollection source="{bookData.bookName}"/>
<mx:Repeater dataProvider="{bookArray}">
<mx:Label text="Place Book Title Here"/>
<mx:Button label="Add to Cart"/>
</mx:Repeater>
9.运行代码,如图8-2。
图8-2.添加Button控制器的Repeater组件
很明显,你不想要你的最终label显示“Place Book Title Here”。你要添加书的实际名字。为了实现这个效果,你需要修改一下你的代码。
8.1.1 在Repeater组件中传递数据
每次Repeater组件创建一个新的循环,它就推进到Array的下一个元素。Repeater类有两个重要的属性你必须熟悉:currentIndex和currentItem。currentIndex返回所选条目的索引数,以0开始。currentItem返回所选条目的实际数据。这些属性在今天的大多数编程环境中是非常标准的。
如果你打开Repeater类的帮助文档,你会发现这两个条目在properties下罗列出来,如图8-3。
图8-3.Repeater类属性
如你所见,currentIndex返回Repeater组件正在处理的条目的数组索引数。而currentItem返回所处理的条目的实际数据。
让我们看个例子:
1.把Label控制器的text属性调整如下:
<mx:Label text="{bookRepeater.currentItem}"/>
此处Label控制器向回调用Repeater组件。它询问Repeater关于currentItem或数据。然后Repeater组件在当前元素中将数据返回到调用者,本例中就是Label控制器的text属性。
2.修改Label组件之后保存并运行你的代码。如图8-4。
图8-4.数据添加到Label控制器上
currentIndex属性返回被Repeater组件处理的元素的索引数,以0开始。当你需要数字时候这个非常有帮助。
3.下一步,你要在Label的text属性中创建一个简单的串联(concatenation)。修改如下:
<mx:Label text="{bookRepeater.currentIndex} {bookRepeater.currentItem}"/>
注意此处,跟其它编程语言例如ActionScript,C++,Java等不同,你不需要用+号来建立一个串联。在MXML中,你所做的就是使用这两个调用并且在它们之间放置一个空格。
4.保存并运行程序。如图8-5。
图8-5.添加了编号的Repeater组件
我靠!回想一下,数组以0开始。如果你现在运行程序,我敢用我的左侧睾丸打赌,你肯定不想看到此处的标记以0开始。
5.按照如下步骤修改你的代码就可解决问题:
<mx:Label text="{bookRepeater.currentIndex + 1} {bookRepeater.currentItem}"/>
6.再次运行程序,图8-6显示问题搞定了。
图8-6.Repeater组件中的固定编号
Button类以及其它的涉及形状条目的类,都有一个称作getRepeaterItem()的方法(看图8-7)。它跟currentItem功能一样,因为Repeater容器外部的控制器可以调用这个Repeater并可以请求它正在处理的条目。
图8-7.getRepeaterItem()函数帮助文档
*****currentItem不可以用在Repeater组件外部,因为它所引用的条目就是Repeater当前正在处理的。当你看到所有东西都显示时,Repeater已经搞定了,currentItem不可以再访问了。
7.添加一个click条目到Button控制器并将event对象传递到一个函数getBookData(),你马上就创建它。
<mx:Button label="Add to Cart" click="getBookData(event)"/>
8.在那个块中创建一个Script块和一个函数getBookData()。将event传递给那个函数,类型为Event。
<mx:Script>
<![CDATA[
private function getBookData(evt:Event):void
{
}
]]>
</mx:Script>
回想一下event对象的target属性让你访问那个事件(本例中是Button控制器)的广播器(broadcaster)的所有属性和函数。本练习中,你将使用Button的getRepeaterItem()从Repeater组件中得到条目并将这些信息传递到一个Label控制器,此控制器叫做nameLabel,我们马上创建它。
9.在你刚刚创建的getBookData()函数中添加如下代码:
private function getBookData(evt:Event):void
{
nameLabel.text = evt.target.getRepeaterItem();
}
10.在Repeater控制器下插入一个Label控制器,其id属性为nameLabel。将fontSize属性设置为14。
<mx:Label fontSize="14"/>
完成的代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
<![CDATA[
private function getBookData(evt:Event):void
{
nameLabel.text = evt.target.getRepeaterItem();
}
]]>
</mx:Script>
<mx:Model >
<books>
<bookName>The Essential Guide to Dreamweaver CS3</bookName>
<bookName>Foundation Flex for Developers: Data-Driven Applications</bookName>
<bookName>Flash CS3 for Designers</bookName>
</books>
</mx:Model>
<mx:ArrayCollection source="{bookData.bookName}"/>
<mx:Repeater dataProvider="{bookArray}">
<mx:Label text="{bookRepeater.currentIndex + 1} {bookRepeater.currentItem}"/>
<mx:Button label="Add to Cart" click="getBookData(event)"/>
</mx:Repeater>
<mx:Label fontSize="14"/>
</mx:Application>
11.保存并运行程序。当你点击这三个按钮中的任一个时,你会发现Label控制器应答于book title,如图8-8。
图8-8.组装上新的Label控制器
你现在要把注意力转向如何中从一个XML文件引进你的数据。如你所见,这跟主题有些变化。