aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/mozilla/tech/xul/tutorial/templates/index.html
blob: 01b1eb0cf40d2956efc9125c01b0ec44b5bcb6ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
---
title: XUL_教程/模板(Templates)
slug: Mozilla/Tech/XUL/Tutorial/Templates
translation_of: Archive/Mozilla/XUL/Tutorial/Templates
---
<p> </p>
<p>在这一小节,我们将学习如果使用数据填充元素。</p>
<h3 id="填充元素(Populating_Elements)">填充元素(Populating Elements)</h3>
<p>XUL提供了通过RDF数据建立元素的方法,来源可以是一个RDF文件,也可以是一个内部数据源。Mozilla本身提供了很多数据源,比如书签、历史记录、邮件列表等。我们在下一小节会针对这部分进行更多的讨论。</p>
<p>我们通常会向treeitems和menuitems这类的元素填充数据。但你完全可以根据实际情况向其他元素填充数据。在这里,我们还是从这些其他元素入手开始讲解,因为实现树型和菜单需要的代码比较多。</p>
<p>为了使用RDF数据建立元素,首先要为这些元素提供一个复制用的模板。实际上,我们只是提供了第一个元素而已,剩下的元素都是在第一个元素的基础上构造出来的。</p>
<p>模板是通过<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素建立的。<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素里用于放置那些新构建元素的内容。<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素要置于包含新构建元素的容器中,比如说你要创建一个<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_tree.html">tree</a>元素,那么就要把<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素置于<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_tree.html">tree</a>元素中。</p>
<p>上面这些通过一个简单的例子来说明会很直观明了,在这个例子中,我们会为每个书签都建立 一个按钮。Mozilla提供了一个书签的数据源,我们可以直接拿来使用,为了简便,我们只取最顶层的书签(也可能是文件夹)来建立按钮。对于那些子标 签,我们可能会通过树型结构或者菜单等来显示这种层叠的结构。</p>
<p>这个例子和其他直接引用内部数据源的程序一样,只能通过chrome开头的地址来调用,处于安全考虑,Mozilla禁止从其他数据源间接调用内部数据源。</p>
<p>为了运行这个例子,你需要建立一个chrome包并把文件都置于包中,这时就可以通过在浏览器的地址栏输入chrome地址运行了。</p>
<p>示例 9.2.1: <a class="external" href="http://www.xulplanet.com/tutorials/xultu/examples/ex_templates_1.xul.txt">下载</a></p>
<div class="examplec">
 <pre>&lt;vbox datasources="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:bookmarks" ref="NC:BookmarksRoot" flex="1"&gt;
  &lt;<a class="bodytag" href="http://www.yeeyan.com/articles/tag/template"><em>template</em></a>&gt;
    &lt;button uri="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:*" label="rdf:http://home.netscape.com/NC-rdf#Name"/&gt;
  &lt;/<a class="bodytag" href="http://www.yeeyan.com/articles/tag/template"><em>template</em></a>&gt;
&lt;/vbox&gt;</pre>
</div>
<p><img align="right" alt="" height="166" src="http://www.xulplanet.com/tutorials/xultu/images/templates1.jpg" width="107"> 在这个例子中,建立了一个vbox,vbox里面包含一列的按钮,每个按钮都对应一个顶级的书签。你可以注意到<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素内只有一个<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_button.html">button</a>元素。这个唯一的按钮元素是所有按钮元素建立的基础。旁边的图片就是最后的运行结果,每个按钮对应于一个书签。</p>
<p>你可以试着在保持这个例子打开的情况下,向浏览器添加一个书签,你会发现这个例子中会立刻添加一个按钮,对应于你刚刚添加的那个书签。(你可能需要重新激活这个窗口,这样才能看到结果)</p>
<p>模板本身被置于vbox中,而box容器有两个特性专门是为模板服务的,可以标识数据的来源。第一个是datasource特性,用来声明用来建立元素的RDF数据源。在这个例子中,对应的是<a class="bodytag external" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:bookmarks。你一定可以猜到这个RDF对应的就是书签数据源。这个数据源是由Mozilla提供的。如果要使用自己的数据源,只需要在datasources特性中指定自定义的RDF地址就可以,就像下面例子中的一样:</p>
<div class="sample">
 <pre>&lt;box datasources="chrome://zoo/content/animals.<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>"
     ref="http://www.some-fictitious-zoo.com/all-animals"&gt;</pre>
</div>
<p>也还可以同时设置多个数据源,只要在不同的数据源地址间加上空格就可以。这通常用于显示多个来源的数据。</p>
<p>ref特性用于说明你想从数据源获取哪些数据。在这个书签的例子中,使用的是NC:<span class="aval">BookmarksRoot</span>,对应的是最顶级的书签。ref具体取什么值依赖于要使用的数据源。如果你使用自己的RDF文件作为数据源,ref的value值通常被设置为Bag、Seq或者Alt元素的about特性的值。</p>
<p>当向box容器添加了这两个特性以后,就可以使用模板来生成元素了。模板里的元素要使用不同的方式来声明。你应该注意到上面例子中,<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_button.html">button</a>元素设置了uri特性,同时为label特性设置了一个特殊含义的值。</p>
<p>模板里的特性值如果是以“<a class="bodytag external" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:”开头的,就表明这个值是要从数据源中读取的。在上面的例子中,label特性就是这种情况。value中除了“rdf:”的剩余部分由命名空间和属性名称组成,表明要使用数据源中的name属性。如果你对这部分感到迷糊,请重新阅读《<a class="external" href="http://cuimingda.com/2008/10/xul-tutorial-introduction-to-rdf.html">XUL教程 - 9.1 - RDF概述</a>》的最后一段。那个例子描述了RDF中的资源是怎样被指向的。在这里我们只使用name属性,当然其他属性在这里也是可以使用的。</p>
<p>我们为这些按钮的label特性设置了特定的URI,是因为我们需要用RDF数据源中的name属性来填充label。我们可以把URI放到按钮的 任何一个特性中,放到其他元素中也是可以的。不管放到哪个特性中,都会被数据源中相应的值替换。最后的结果,就是我们用按钮label显示出了每个书签的 名字。</p>
<p>下面的例子展示了我们如何为按钮的其他特性设置数据源。当然我们已经假设数据源中包含相应的资源。如果需要的资源在数据源中没有被找到,那么特性的value就会被设置为空字符串。</p>
<div class="sample">
 <pre>&lt;button class="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:http://www.example.com/rdf#class"
        uri="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:*"
        label="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:http://www.example.com/rdf#name"/&gt;
        crop="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:http://www.example.com/rdf#crop"/&gt;</pre>
</div>
<p>如上面例子所示,你可以通过不同的数据源动态设置元素的每个特性。</p>
<p>uri特性用定义开始生成内容的元素。之前的内容只会生成一次,而之后的内容会每次都生成。在后面通过模板建立树型元素的例子中,我们将对这点进行更加详细的阐述。</p>
<p>当我们将这些特性添加进模板所在的容器后(在这个例子中是box),就可以使用外部数据来建立各种有趣的列表了。我们当然可以在模板中多放几个元素,也可以在任何元素的特性上添加RDF引用,下面就是一个例子:</p>
<p>实例 9.2.2: <a class="external" href="http://www.xulplanet.com/tutorials/xultu/examples/ex_templates_2.xul.txt">下载</a></p>
<div class="examplec">
 <pre>&lt;vbox datasources="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:bookmarks" ref="NC:BookmarksRoot" flex="1"&gt;
  &lt;<a class="bodytag" href="http://www.yeeyan.com/articles/tag/template"><em>template</em></a>&gt;
    &lt;vbox uri="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:*"&gt;
      &lt;button label="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:http://home.netscape.com/NC-rdf#Name"/&gt;
      &lt;label value="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:http://home.netscape.com/NC-rdf#URL"/&gt;
    &lt;/vbox&gt;
  &lt;/<a class="bodytag" href="http://www.yeeyan.com/articles/tag/template"><em>template</em></a>&gt;
&lt;/vbox&gt;</pre>
</div>
<p>这个模板建立了一个vbox,容器中每个书签都对应于一个按钮和一个标签。按钮上显示的是书签的名字,标签上显示的是书签的地址。</p>
<p>新建立的元素从功能上来说,和直接向XUL中添加数据是没有差别的。每一个通过模板建立的元素都会被自动添加id特性,用来标识这个资源,你也可以使用这个特性对每个资源进行引用。</p>
<p>你还可以在同一个特性的值中,定义多个不同的资源,中间用空格分隔,下面就是一个例子。可以在<a class="external" href="http://www.xulplanet.com/tutorials/xultu/templateex.html">这里</a>查看更多关于资源定义的语法。</p>
<p>示例 9.2.3: <a class="external" href="http://www.xulplanet.com/tutorials/xultu/examples/ex_templates_3.xul.txt">源代码</a></p>
<div class="examplec">
 <pre>&lt;vbox datasources="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:bookmarks" ref="NC:BookmarksRoot"
     flex="1"&gt;
  &lt;<a class="bodytag" href="http://www.yeeyan.com/articles/tag/template"><em>template</em></a>&gt;
    &lt;label uri="<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:*" value="rdf:http://home.netscape.com/NC-rdf#Name
<a class="bodytag" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:http://home.netscape.com/NC-rdf#URL"/&gt;
  &lt;/<a class="bodytag" href="http://www.yeeyan.com/articles/tag/template"><em>template</em></a>&gt;
&lt;/vbox&gt;</pre>
</div>
<h3 id="建立模板(How_Templates_are_Built)">建立模板(How Templates are Built)</h3>
<p>一旦为元素设置了datasources特性,就表明这个元素将会通过模板来生成。要明确这点,是否生成内容不是由<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>标 记决定的,而是由atasources特性来决定的。只要设置了这个特性,元素就会自动被添加一个叫做构造器的对象。这个对象的责任就是通过模板来构建内 容。在JavaSciprt中,你可以使用builder属性来访问这个构造器对象,但通常你只有在需要手动重新生成内容的时候才需要调用这个对象。</p>
<p>构造器有两种类型,最常用的是内容构造器(content builder),另外一种是树型构造器(tree builder),当然只有在构造树型元素的时候才用的到。</p>
<p>内容构造器从<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素中读取内容,并在每行都进行复制。比如在上面的例子中如果有十个书签,就会构建10个<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_label.html">label</a>元素,并都会添加到<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_vbox.html">vbox</a>元素下面。如果你使用DOM函数对树型结构进行遍历,你可以找到这些元素,并可以调用它们的属性。这些元素最终会在界面显示出来,但是<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素本身是不会显示的,虽然在DOM中是可以找到<a class="tag external" href="http://www.xulplanet.com/references/elemref/ref_template.html">template</a>元素的。另外,每个label的id特性将被设置为RDF资源中对应的值。</p>
<p>内容构造器总是从uri="<a class="bodytag external" href="http://www.yeeyan.com/articles/tag/rdf"><em>rdf</em></a>:*"定义的地方开始操作。如果uri特性所在的元素不是在第一行,那么之前的元素都值将被建立一次。下面的例子中会建立一个hbox,hbox内会用一组label来填充。</p>
<p>--------------------------------------------------------------------------------</p>
<p>本文完整内容请参见:</p>
<p><a class="external" href="http://cuimingda.com/2008/10/xul-tutorial-templates.html">http://cuimingda.com/2008/10/xul-tutorial-templates.html</a></p>