Please note, this is a STATIC archive of website developer.mozilla.org from November 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

XUL_教程/模板(Templates)

 

在这一小节,我们将学习如果使用数据填充元素。

填充元素(Populating Elements)

XUL提供了通过RDF数据建立元素的方法,来源可以是一个RDF文件,也可以是一个内部数据源。Mozilla本身提供了很多数据源,比如书签、历史记录、邮件列表等。我们在下一小节会针对这部分进行更多的讨论。

我们通常会向treeitems和menuitems这类的元素填充数据。但你完全可以根据实际情况向其他元素填充数据。在这里,我们还是从这些其他元素入手开始讲解,因为实现树型和菜单需要的代码比较多。

为了使用RDF数据建立元素,首先要为这些元素提供一个复制用的模板。实际上,我们只是提供了第一个元素而已,剩下的元素都是在第一个元素的基础上构造出来的。

模板是通过template元素建立的。template元素里用于放置那些新构建元素的内容。template元素要置于包含新构建元素的容器中,比如说你要创建一个tree元素,那么就要把template元素置于tree元素中。

上面这些通过一个简单的例子来说明会很直观明了,在这个例子中,我们会为每个书签都建立 一个按钮。Mozilla提供了一个书签的数据源,我们可以直接拿来使用,为了简便,我们只取最顶层的书签(也可能是文件夹)来建立按钮。对于那些子标 签,我们可能会通过树型结构或者菜单等来显示这种层叠的结构。

这个例子和其他直接引用内部数据源的程序一样,只能通过chrome开头的地址来调用,处于安全考虑,Mozilla禁止从其他数据源间接调用内部数据源。

为了运行这个例子,你需要建立一个chrome包并把文件都置于包中,这时就可以通过在浏览器的地址栏输入chrome地址运行了。

示例 9.2.1: 下载

<vbox datasources="rdf:bookmarks" ref="NC:BookmarksRoot" flex="1">
  <template>
    <button uri="rdf:*" label="rdf:https://home.netscape.com/NC-rdf#Name"/>
  </template>
</vbox>

在这个例子中,建立了一个vbox,vbox里面包含一列的按钮,每个按钮都对应一个顶级的书签。你可以注意到template元素内只有一个button元素。这个唯一的按钮元素是所有按钮元素建立的基础。旁边的图片就是最后的运行结果,每个按钮对应于一个书签。

你可以试着在保持这个例子打开的情况下,向浏览器添加一个书签,你会发现这个例子中会立刻添加一个按钮,对应于你刚刚添加的那个书签。(你可能需要重新激活这个窗口,这样才能看到结果)

模板本身被置于vbox中,而box容器有两个特性专门是为模板服务的,可以标识数据的来源。第一个是datasource特性,用来声明用来建立元素的RDF数据源。在这个例子中,对应的是rdf:bookmarks。你一定可以猜到这个RDF对应的就是书签数据源。这个数据源是由Mozilla提供的。如果要使用自己的数据源,只需要在datasources特性中指定自定义的RDF地址就可以,就像下面例子中的一样:

<box datasources="chrome://zoo/content/animals.rdf"
     ref="https://www.some-fictitious-zoo.com/all-animals">

也还可以同时设置多个数据源,只要在不同的数据源地址间加上空格就可以。这通常用于显示多个来源的数据。

ref特性用于说明你想从数据源获取哪些数据。在这个书签的例子中,使用的是NC:BookmarksRoot,对应的是最顶级的书签。ref具体取什么值依赖于要使用的数据源。如果你使用自己的RDF文件作为数据源,ref的value值通常被设置为Bag、Seq或者Alt元素的about特性的值。

当向box容器添加了这两个特性以后,就可以使用模板来生成元素了。模板里的元素要使用不同的方式来声明。你应该注意到上面例子中,button元素设置了uri特性,同时为label特性设置了一个特殊含义的值。

模板里的特性值如果是以“rdf:”开头的,就表明这个值是要从数据源中读取的。在上面的例子中,label特性就是这种情况。value中除了“rdf:”的剩余部分由命名空间和属性名称组成,表明要使用数据源中的name属性。如果你对这部分感到迷糊,请重新阅读《XUL教程 - 9.1 - RDF概述》的最后一段。那个例子描述了RDF中的资源是怎样被指向的。在这里我们只使用name属性,当然其他属性在这里也是可以使用的。

我们为这些按钮的label特性设置了特定的URI,是因为我们需要用RDF数据源中的name属性来填充label。我们可以把URI放到按钮的 任何一个特性中,放到其他元素中也是可以的。不管放到哪个特性中,都会被数据源中相应的值替换。最后的结果,就是我们用按钮label显示出了每个书签的 名字。

下面的例子展示了我们如何为按钮的其他特性设置数据源。当然我们已经假设数据源中包含相应的资源。如果需要的资源在数据源中没有被找到,那么特性的value就会被设置为空字符串。

<button class="rdf:https://www.example.com/rdf#class"
        uri="rdf:*"
        label="rdf:https://www.example.com/rdf#name"/>
        crop="rdf:https://www.example.com/rdf#crop"/>

如上面例子所示,你可以通过不同的数据源动态设置元素的每个特性。

uri特性用定义开始生成内容的元素。之前的内容只会生成一次,而之后的内容会每次都生成。在后面通过模板建立树型元素的例子中,我们将对这点进行更加详细的阐述。

当我们将这些特性添加进模板所在的容器后(在这个例子中是box),就可以使用外部数据来建立各种有趣的列表了。我们当然可以在模板中多放几个元素,也可以在任何元素的特性上添加RDF引用,下面就是一个例子:

实例 9.2.2: 下载

<vbox datasources="rdf:bookmarks" ref="NC:BookmarksRoot" flex="1">
  <template>
    <vbox uri="rdf:*">
      <button label="rdf:https://home.netscape.com/NC-rdf#Name"/>
      <label value="rdf:https://home.netscape.com/NC-rdf#URL"/>
    </vbox>
  </template>
</vbox>

这个模板建立了一个vbox,容器中每个书签都对应于一个按钮和一个标签。按钮上显示的是书签的名字,标签上显示的是书签的地址。

新建立的元素从功能上来说,和直接向XUL中添加数据是没有差别的。每一个通过模板建立的元素都会被自动添加id特性,用来标识这个资源,你也可以使用这个特性对每个资源进行引用。

你还可以在同一个特性的值中,定义多个不同的资源,中间用空格分隔,下面就是一个例子。可以在这里查看更多关于资源定义的语法。

示例 9.2.3: 源代码

<vbox datasources="rdf:bookmarks" ref="NC:BookmarksRoot"
     flex="1">
  <template>
    <label uri="rdf:*" value="rdf:https://home.netscape.com/NC-rdf#Name 
rdf:https://home.netscape.com/NC-rdf#URL"/>
  </template>
</vbox>

建立模板(How Templates are Built)

一旦为元素设置了datasources特性,就表明这个元素将会通过模板来生成。要明确这点,是否生成内容不是由template标 记决定的,而是由atasources特性来决定的。只要设置了这个特性,元素就会自动被添加一个叫做构造器的对象。这个对象的责任就是通过模板来构建内 容。在JavaSciprt中,你可以使用builder属性来访问这个构造器对象,但通常你只有在需要手动重新生成内容的时候才需要调用这个对象。

构造器有两种类型,最常用的是内容构造器(content builder),另外一种是树型构造器(tree builder),当然只有在构造树型元素的时候才用的到。

内容构造器从template元素中读取内容,并在每行都进行复制。比如在上面的例子中如果有十个书签,就会构建10个label元素,并都会添加到vbox元素下面。如果你使用DOM函数对树型结构进行遍历,你可以找到这些元素,并可以调用它们的属性。这些元素最终会在界面显示出来,但是template元素本身是不会显示的,虽然在DOM中是可以找到template元素的。另外,每个label的id特性将被设置为RDF资源中对应的值。

内容构造器总是从uri="rdf:*"定义的地方开始操作。如果uri特性所在的元素不是在第一行,那么之前的元素都值将被建立一次。下面的例子中会建立一个hbox,hbox内会用一组label来填充。

--------------------------------------------------------------------------------

本文完整内容请参见:

https://cuimingda.com/2008/10/xul-tutorial-templates.html

文档标签和贡献者

 此页面的贡献者: ziyunfei, Sheppy, bjandrew
 最后编辑者: ziyunfei,