mozilla

Revision 275597 of 模板:编译Rule

  • Revision slug: User_talk:Dongdong/编辑­Rule
  • Revision title: 模板:编译Rule
  • Revision id: 275597
  • Created:
  • Creator: Dongdong
  • Is current revision? Yes
  • Comment 8 words added, 77 words removed

Revision Content

上一页User_talk:Dongdong                                下一页User_talk:Dongdong/产生结果

Query
Edit section

一个XUL模板是由一个查询条件和一系列Rules条件组成的。一个查询条件中包括了关于如何从数据源中取数据的指示。不同的数据源有不同的语法。 例如,如果是SQLite数据源,一个SQL语句就是查询条件。这就能产生一组结果并以此得到最终想要的结果。如果是RDF或XML,查询条件就包括了一 组用于浏览RDF图和DOM结点的指示。查询条件是在query标签中声明的(Firefox3中支持这个语法,Firefox2中只支持RDF数据源并 且没有query这个标签),query标签直接放在template标签内。query是用来产生一组结果集的。

Rules
Edit section

模板也包括了一组规则(Rules),用于从不同的条件产生不同的结果。还有在后面我们要谈到的attribute置换语法,用来得到并变更从模板中得到的结果值。规则是用rule标记定义的,你可以定义多个规则。从query得到的结果都会经过规则的过滤,最终得到的数据就是满足规则的数据。需要注意的是,数据找到满足条件的第一个规则后,其它的规则将不再对该数据进行过滤。例如,第一个规则如果过滤书,那么第二个规则就只能对杂志进行过滤。也就是说,数据过滤一个就少一个。按这种方式,不同的数据产生不同的结果。

在很多情况下,你只需要一个规则,因为你想让所有数据按照一个规则过滤。比如,你在产生一个列表框时,只通常只会用一个规则。如果只需要一个规则,可以不定义rule标记。一个没有任何规则的模板会对每个数据进行无条件过滤。

Template语法概要
Edit section

下面是模板语法概要

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A" flex="1">
  <template>
    <query>
      -- query content goes here --
    </query>
    <rule>
      -- rule content goes here --
    </rule>
    <rule>
      -- rule content goes here --
    </rule>
  </template>
</vbox>

 

Query/rule 的编译与结果集的惰性产生机制

当模板构建器开始处理数据,并在它开始加载数据源后,它必须编译Query和Rule.这个步骤包括分析查询规则并将之转换为内部数据结构。因此,如果动态改变规则将不会有任何效果。然而,通过调用builder.rebuild重构模板时,会对查询规则进行重新编译,并再次应用模板。这就意味着你可以用DOM方法来改变规则,重构模板然后得到新的不同的结果。

一旦模板构建器编译完规则,查询和产生结果集的过程就开始了。模板构建器产生结果集的过程是很懒惰的,它只在需要的时候才进行处理。例如,考虑下面这个例子:

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A" hidden="true">
  <template>
    ...
  </template>
</vbox>

这个例子中vbox通过hidden属性隐藏了。此时,模板构建器将不会做任何事情,因为产生了任何结果集也不能被显示,构建器将推迟它的工作。如果你把vbox的隐藏属性去掉,模板构建器会被激活,并产生你想要的结果集。

那这是不是意味着模板不能用在界面中的隐藏部分呢?不是的,你一样可以使用。将元素的隐藏属性去掉并不是唯一促使构建器产生结果的方法。 调用DOM API去获取产生的结果集同样能够触发模板构建器去产生结果集。例如,就对刚才的那个vbox调用如下的函数就能起到这个效果。

var length = vbox.childNodes.length;

这段代码请求获取vbox的子结点个数,它会触发模板构建器去处理查询并产生结果集。当处理完成,正确的子结点长度就返回了。

所有这些,对XUL的开发者都是不可见的。模板构建器什么时候开始产生结果是自动的,你不需要做任何事情。但是,在两种情况下结果集不会自动产生:菜单和tree的子结点treeitem。

菜单中的内容直到菜单弹出时才会开始产生。 这个也在情理之中,因为不打开菜单,用户是看不到其内容的。然而,这也意味着就算通过上面的方式(获取子结点长度),也不能让模板构建器产生结果,还是要等菜单弹出。这是一个很大的不同。同样的情形也存在于tree的子结点中,用户如果不去触发tree中的折叠器(就是平常看到的+ -),或者通过代码打开一行,tree的模板构建器也不会产生结果集。

这个惰性机制在菜单和tree的递归处理上是很能派上用场的,因为在tree中显示每个treeitem会很费时间的。模板构建器有时会更懒惰:如果产生的结果集本身就含有隐藏元素,这些元素将在必要时才产生。

Revision Source

<p><strong>上一页<a href="/User_talk:Dongdong" title="User_talk:Dongdong">User_talk:Dongdong</a></strong>                                <strong>下一页</strong><a href="/User_talk:Dongdong/%E4%BA%A7%E7%94%9F%E7%BB%93%E6%9E%9C" title="User_talk:Dongdong/产生结果">User_talk:Dongdong/产生结果</a></p>
<h3 class="editable" id="_Query_

"><span> Query </span>
<div class="editIcon"><a href="/../../../../en/XUL/Template_Guide/Rule_Compilation#" style="visibility: hidden;" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
</h3>
<p>一个XUL模板是由一个查询条件和一系列Rules条件组成的。一个查询条件中包括了关于如何从数据源中取数据的指示。不同的数据源有不同的语法。 例如,如果是SQLite数据源,一个SQL语句就是查询条件。这就能产生一组结果并以此得到最终想要的结果。如果是RDF或XML,查询条件就包括了一 组用于浏览RDF图和DOM结点的指示。查询条件是在query标签中声明的(Firefox3中支持这个语法,Firefox2中只支持RDF数据源并 且没有query这个标签),query标签直接放在template标签内。query是用来产生一组结果集的。</p>
<h3 class="editable" id="_Rules_

"><span> Rules </span>
<div class="editIcon"><a href="/../../../../en/XUL/Template_Guide/Rule_Compilation#" style="visibility: hidden;" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
</h3>
<p>模板也包括了一组规则(Rules),用于从不同的条件产生不同的结果。还有在后面我们要谈到的attribute置换语法,用来得到并变更从模板中得到的结果值。规则是用rule标记定义的,你可以定义多个规则。从query得到的结果都会经过规则的过滤,最终得到的数据就是满足规则的数据。需要注意的是,数据找到满足条件的第一个规则后,其它的规则将不再对该数据进行过滤。例如,第一个规则如果过滤书,那么第二个规则就只能对杂志进行过滤。也就是说,数据过滤一个就少一个。按这种方式,不同的数据产生不同的结果。</p>
<p>在很多情况下,你只需要一个规则,因为你想让所有数据按照一个规则过滤。比如,你在产生一个列表框时,只通常只会用一个规则。如果只需要一个规则,可以不定义rule标记。一个没有任何规则的模板会对每个数据进行无条件过滤。</p>
<h3 class="editable" id="_Template.E8.AF.AD.E6.B3.95.E6.A6.82.E8.A6.81

"><span> Template语法概要</span>
<div class="editIcon"><a href="/../../../../en/XUL/Template_Guide/Rule_Compilation#" style="visibility: hidden;" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
</h3>
<p>下面是模板语法概要</p>
<pre>&lt;vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A" flex="1"&gt;
  &lt;template&gt;
    &lt;query&gt;
      -- query content goes here --
    &lt;/query&gt;
    &lt;rule&gt;
      -- rule content goes here --
    &lt;/rule&gt;
    &lt;rule&gt;
      -- rule content goes here --
    &lt;/rule&gt;
  &lt;/template&gt;
&lt;/vbox&gt;
</pre>
<p> </p>
<h3 class="editable" id="_Query/rule_.E7.9A.84.E7.BC.96.E8.AF.91.E4.B8.8E.E7.BB.93.E6.9E.9C.E9.9B.86.E7.9A.84.E6.83.B0.E6.80.A7.E4.BA.A7.E7.94.9F.E6.9C.BA.E5.88.B6
"><span> Query/rule 的编译与结果集的惰性产生机制</span><span><br>
</span></h3>
<p>当模板构建器开始处理数据,并在它开始加载数据源后,它必须编译Query和Rule.这个步骤包括分析查询规则并将之转换为内部数据结构。因此,如果动态改变规则将不会有任何效果。然而,通过调用builder.rebuild重构模板时,会对查询规则进行重新编译,并再次应用模板。这就意味着你可以用DOM方法来改变规则,重构模板然后得到新的不同的结果。</p>
<p>一旦模板构建器编译完规则,查询和产生结果集的过程就开始了。模板构建器产生结果集的过程是很懒惰的,它只在需要的时候才进行处理。例如,考虑下面这个例子:</p>
<pre>&lt;vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A" hidden="true"&gt;
  &lt;template&gt;
    ...
  &lt;/template&gt;
&lt;/vbox&gt;
</pre>
<p>这个例子中vbox通过hidden属性隐藏了。此时,模板构建器将不会做任何事情,因为产生了任何结果集也不能被显示,构建器将推迟它的工作。如果你把vbox的隐藏属性去掉,模板构建器会被激活,并产生你想要的结果集。</p>
<p>那这是不是意味着模板不能用在界面中的隐藏部分呢?不是的,你一样可以使用。将元素的隐藏属性去掉并不是唯一促使构建器产生结果的方法。 调用DOM API去获取产生的结果集同样能够触发模板构建器去产生结果集。例如,就对刚才的那个vbox调用如下的函数就能起到这个效果。</p>
<pre>var length = vbox.childNodes.length;
</pre>
<p>这段代码请求获取vbox的子结点个数,它会触发模板构建器去处理查询并产生结果集。当处理完成,正确的子结点长度就返回了。</p>
<p>所有这些,对XUL的开发者都是不可见的。模板构建器什么时候开始产生结果是自动的,你不需要做任何事情。但是,在两种情况下结果集不会自动产生:菜单和tree的子结点treeitem。</p>
<p>菜单中的内容直到菜单弹出时才会开始产生。 这个也在情理之中,因为不打开菜单,用户是看不到其内容的。然而,这也意味着就算通过上面的方式(获取子结点长度),也不能让模板构建器产生结果,还是要等菜单弹出。这是一个很大的不同。同样的情形也存在于tree的子结点中,用户如果不去触发tree中的折叠器(就是平常看到的+ -),或者通过代码打开一行,tree的模板构建器也不会产生结果集。</p>
<p>这个惰性机制在菜单和tree的递归处理上是很能派上用场的,因为在tree中显示每个treeitem会很费时间的。模板构建器有时会更懒惰:如果产生的结果集本身就含有隐藏元素,这些元素将在必要时才产生。</p>
Revert to this revision