每个 JSF 组件都有一些特定于它的属性集。同时,几乎所有 UI 组件都有所有这些组件共有的属性。例如,onclick, ondblclick, onblur, onmouseover, onmouseout, onmousedown等等。它们被称为 PassThru,因为它们是一对一渲染到最终的 HTML 布局。

RichFaces CDK 使用一个特殊的元属性x:passThruWithExclusions。例如,

<div x:passThruWithExclusions="id,value,styleClass,class" ....>

此属性指示将除明确提到的属性之外的所有 PassThru 属性作为属性插入到该特定 div 中。只有一个属性,简短且不难。让我们看看 JSF 2.0 PDL 如何帮助。

在关于 PDL 的第一篇文章中,我们为了简单起见定义了只有四种样式类型属性。

<composite:interface>
    <composite:attribute name="style" required="false"/>
    <composite:attribute name="styleClass" required="false"/>
    <composite:attribute name="headerClass" required="false"/>
    <composite:attribute name="bodyClass" required="false"/>
</composite:interface>

现在,我们将完成缺失的部分。根据 rich panel TLD 文档,它有 10 个 PathThru onxxxxxx 属性。为了测试它们的工作方式,让我们将以下内容添加到测试页面

  <rich4:panel onmouseover="this.style.backgroundColor='#F9F9FF'"
      onmouseout="this.style.backgroundColor='#FFF'">
   <f:facet name="header">
    <h:outputText value="This is a header"/>
   </f:facet>
   <h:outputText value="panel with header"/>
  </rich4:panel>

顺便说一句,上面的composite:interface包含四个样式属性的明确声明。如果我们像这样删除它们会怎样

<composite:interface>
</composite:interface>

实际上,没有任何变化。组件及其样式工作没有任何变化。这是因为 Facelets 的特性,当 Facelets 传递由最终开发者定义的任何属性时,而不是经典的 JSP,在 TLD 文件中缺少属性名称是一个大问题。让我们把 Facelets 的这个特性看作是一个优点,至少对于组件代码的大小来说是这样。

一滴毒液可以毒化一桶酒 - 如果你属性名称有误,找出错误是你的个人问题。没有任何警告。然而,即使在composite:interface中明确声明属性,即使有required="true"也没有帮助。仍然沉默。

composite:interface在任何情况下都是有意义的。是的!!!不要忘记JSF市场中最出色的关键词——工具。如果JSF工具足够智能,它会给你一个可能的属性列表,按优先级排序,帮助签名方法等等。根据复合:属性的pdldoc,它有许多对工具很有用的属性。

让我们回到主题。隐式声明属性的能力适用于我们的onmouseover, onmouseout吗?...部分适用。我们不需要在composite:interface部分隐式声明它们(好吧,好吧。我们仍然需要对未来的工具保持友好)。然而,PDL不知道在哪里将它们插入到composite:interface部分。因此,测试示例还没有生效。

Mojarra对PDL的实现没有捷径可以缩短所需代码的大小。复制/粘贴是可行的方法。我们将以下内容添加为顶层div的属性

onclick="r#{compositeComponent.attrs.onclick}"
ondblclick="r#{compositeComponent.attrs.ondblclick}"
onkeydown="r#{compositeComponent.attrs.onkeydown}"
onkeypress="r#{compositeComponent.attrs.onkeypress}"
onkeyup="r#{compositeComponent.attrs.onkeyup}"
onmousedown="r#{compositeComponent.attrs.onmousedown}"
onmousemove="r#{compositeComponent.attrs.onmousemove}"
onmouseout="r#{compositeComponent.attrs.onmouseout}"
onmouseover="r#{compositeComponent.attrs.onmouseover}"
onmouseup="r#{compositeComponent.attrs.onmouseup}"

现在,我们可以看到它是如何工作的: http://livedemo.exadel.com/richfaces4-panel-4/home.jsf

看起来我们一切都准备好了。然而,让我们看看实际上渲染了什么

 <div class="rich-panel " style="" onclick="" ondblclick="" onkeydown="" 
        onkeypress="" onkeyup="" onmousedown="" onmousemove="" 
        onmouseout="this.style.backgroundColor='#FFF'" 
        onmouseover="this.style.backgroundColor='#F9F9FF'" onmouseup="">
   <div class="rich-panel-header ">This is a header
   </div>
 
  <div class="rich-panel-body ">panel with header
  </div> 

 </div>

我们有一堆空属性。即使浏览器可以处理这个问题,但这不是最终应用程序开发者会满意的成果。如果属性为空,则不应出现在结果代码中。到目前为止,我在Mojarra 2.0.0 PR中还没有找到避免它的解决方案。有关问题已提交。


回到顶部