用模板生成树型组件

来源:岁月联盟 编辑:zhuzhu 时间:2008-12-30

  以下是对原文的翻译:

  下面我们来介绍如何使用模板来建立树型组件。

  为树型组件添加数据源(Adding Datasources to Trees)

  只要使用树型组件,就会经常需要使用模板来生成内容,因为这种情况下通常需要操作数量庞大并且分层存储的数据。使用模板建立树型组件和建立其他元素 的语法是很相近的。你需要在tree元素中添加datasources特性和ref特性,这两个特性定义了数据源和要显示数据的根节点。你还可以定义不同 的规则,用来显示不同类型的数据。

  下面这个例子使用了网页历史记录的数据源:

<tree datasources="rdf:history" ref="NC:HistoryByDate"
     flags="dont-build-content">

  正如上一节所说,树型组件可以使用树型构造器来代替内容构造器。这样就意味着不是每条记录都在树型组件中有唯一的元素相对应,这在实际应用中是很有效的。在上面的例子中,flags特性的值被设置为“dont-build-content”,表明使用树型构造器,而不是内容构造器。如果不设置这个特性,还是会使用内容构造器。你可以通过Mozilla的DOM Inspector扩展来对比设置和不设置flags特性时树型组件的内容,就可以理解这个特性的作用。

  如果你坚持使用内容构造器,切记只有在必要时内容才会被生成。对于分层的树型组件来说,只有在展开父节点的时候,才会生成相应的子节点。

  在这个模板中,树型组件中每一列都会对应于一个treecell元素。每个treecell都应该设置label特性,对应于列标题。通常这个特性会被指向一个RDF属性,这样就可以从数据源中动态更新数据。

  下面的例子通过模板构建了一个树型组件,内容是系统的文件结构。

示例 9.3.1: 源代码

<tree id="my-tree" flex="1"
    datasources="rdf:files" ref="file:///" flags="dont-build-content">
<treecols>
<treecol id="Name" label="Name" primary="true" flex="1"/>
<splitter/>
<treecol id="Date" label="Date" flex="1"/>
</treecols>
<template>
 <rule>
  <treechildren>
   <treeitem uri="rdf:*">
    <treerow>
     <treecell label="rdf:http://home.netscape.com/NC-rdf#Name"/>
     <treecell label="rdf:http://home.netscape.com/WEB-rdf#LastModifiedDate"/>
    </treerow>
   </treeitem>
  </treechildren>
 </rule>
</template>
</tree>

  在这个例子中,建立了一个两列的树型组件,分别对应于文件的名称和修改日期。这个树型组件会显示根目录下的文件列表。这里只设置了一条规则,当然我 们可以根据需要额外再增加规则。和其他模板一样,元素上设置的uri特性表明开始生成内容的位置。两列分别从数据源获取名称和日期,并把获取的值更新到 treecell的label上。

  这个例子体现了uri特性的作用。注意在这个例子中,treeitem上添加了uri特性,而且还不是rule元素的直接子元素。我们只能把uri 特性添加到那些需要循环的资源上。因为我们不想让treechildren元素也重复显示,所以这个元素上没有uri特性,而是把这个特性添加到了 treeitem元素上。实际上,包含uri特性的元素之前(外部)的那些元素是不会重复显示的,而带uri特性的这个元素和之后(内部)的元素都将循环 显示。

XUL教程 - 9.3 - 用模板生成树型组件

  注意上面这张图片,顶级元素下面自动填充了子元素。当模板或者规则包含tree元素或者menu元素的时候,XUL会自动生成子元素,只要有需要,模板就会基于现有的RDF数据生成嵌套的tree元素。

  有趣的是,RDF数据源里面的资源只有在需要的时候才会加载。也就是说,在那些分层结构中藏的很深的数据,只有当用户查看这些节点的时候才会加载。这对那些需要动态加载数据的数据源,是非常有效的。

  可以排序的列(Sorting Columns)

  如果你尝试了上面的例子,就会注意到这个列表中的文件没有经过排序,树型组件在通过RDF数据源生成数据的时候是可以选择进行排序的,你可以对任意 列按照升序或者降序进行排序。用户也可以通过点击列标题,随时修改用于排序的列和排序方式。当树型组件中加载的是静态数据时,是不可以排序的,但是你也可 以编写脚本,手动实现排序。

  排序的方式取决于treecol上的三个特性。第一个是sort特性,应该设置为对应于排序字段的RDF属性,通常和treecell的label 特性相呼应。如果在某一列设置了这个特性,那么数据就会按照这一列进行排序。用户可以通过点击列标题改变排序的顺序。如果你不为某个列设置sort特性, 就不能按照这一列进行排序。

  sortDirection特性用于设置排序的默认顺序,可以设置为以下其中的一个值:

  ascending: 数据会按升序进行排序

  descending: 数据会按降序进行排序

  natural: 数据将会按照储存在RDF数据源中的顺序显示

  最后一个是sortActive特性,只能在一个列上将这个特性设置为true,那么这一列就是默认排序的列。

  虽然只要添加上面三个特性就可以实现排序功能,但是你还可以为那些可排序列添加sortDirectionIndicator样式类,添加了这个样 式类以后在列标题上就会显示一个小三角,表明排序的顺序,如果不添加这个样式类,不影响用户使用排序功能,但是就不能随时知道现在是使用哪个列排序,按照 什么样的顺序排列了。

  接下来的例子对上面的例子进行了完善,添加了一些额外的功能:

<treecols>
<treecol id="Name" label="Name" flex="1" primary="true"
      class="sortDirectionIndicator" sortActive="true"
      sortDirection="ascending"
      sort="rdf:http://home.netscape.com/NC-rdf#Name"/>
<splitter/>
<treecol id="Date" label="Date" flex="1" class="sortDirectionIndicator"
      sort="rdf:http://home.netscape.com/WEB-rdf#LastModifiedDate"/>
</treecols>
列状态的持久化(Persisting Column State)

  你可能会想保存当前列的排序状态,这样下次打开的时候就不需要重新设置。为了实现这个功能,我们需要为每个treecol元素添加persist特 性。在这个例子中,有五个特性需要持久化,分别用来保存列宽、排序状态、显示状态、排序列和排序顺序。下面的例子就是一个典型的treecol:

<treecol id="Date" label="Date" flex="1"
       class="sortDirectionIndicator"
       persist="width ordinal hidden sortActive sortDirection"
       sort="rdf:http://home.netscape.com/WEB-rdf#LastModifiedDate"/>
更多的规则特性(Additional Rule Attributes)

  rule元素还可以添加两个额外的特性,用于匹配某些特殊情况,两个特性的值都是布尔值。

  iscontainer

  如果这个特性被设置为true,规则将会匹配所有包含子元素的资源。比如说,我们可以使用这条规则匹配书签文件夹。这个特性是很方便的,这样数据源就不用为了类似的情况增加特别的特性。

  isempty

  如果这个特性被设置为true,规则将会匹配素有不包含子元素的资源。

  这两个特性的作用是正好相反的。一个资源可能是个容器,也可能是空的。但是这和一个非容器是不同的。比如一个书签文件夹是一个容器,但无法确定是否包含子元素,而一个独立的书签或者分隔符肯定不是一个容器。

  你可以把这两个特性和其他特性组合起来判断任何特殊情况。