我有一个用JSF 2.0 + PrimeFaces 3.4编写的标记库,现在我正在尝试更新到JSF 2.2和PrimeFaces 4.0。 但是我意识到传递给组件的属性值在复合组件中得到了评估,并且导致了错误的渲染ID。
enum.xhtml(复合组件)
<cc:interface>
<cc:attribute name="render" default="@this"/>
.....
</cc:interface>
<cc:implementation>
<h:selectOneMenu ......../>
<p:ajax update="#{cc.attrs.render}" process="#{cc.attrs.execute}" />
</cc:implementation>
用法:
<t:enum id="authenticationSource" value="#{authenticationStrategy}" .....
render=":#{cc.clientId}:tabView:passwordVisibility"/>
渲染属性值:#{cc.clientId}:tabView:passwordVisibility
,应为
:j_idt1:j_idt3:j_idt5:editorDialog:j_idt39:j_idt40:tabView:passwordVisibility`
但它被评估为
:j_idt1:j_idt3:j_idt5:editorDialog:j_idt39:j_idt40:tabView:autheticationSource:tabView:passwordVisibility
渲染的属性值在复合组件中计算,导致错误。它应该在它被使用的地方进行评估,就像在JSF 2.0中一样。 是否有任何配置属性或任何东西来克服此错误。
我正在使用wildfly 8.1.0-Final
答案 0 :(得分:4)
这种复合材料设计不正确。您不应该在复合的上下文之外使用#{cc.clientId}
。更一般地说,你不应该从复合材料之外了解复合材料的内部构件。复合材料本身应该担心这一点。
如果您将复合组件嵌套在一起,则此构造将失败。 #{cc}
实际上会引用&#34;当前&#34;复合材料。也许你依赖于旧的JSF实现中的一个错误,其中#{cc}
范围在嵌套的复合组件之后没有被正确清除(即它将引用最后指定的值而不是可用的值。当前背景)。
也许你是过度使用复合组件的受害者,只是因为与常规标签文件/包含相比,零配置性质。有关何时使用其中一个的详细信息,请前往When to use <ui:include>, tag files, composite components and/or custom components?到目前为止,仅使用复合,并且仅当您要将一堆密切相关的组件绑定到单个 bean属性,因此肯定不会对整个&#34;有几个属性的bean。
如果您绝对肯定复合材料是满足您需求的正确解决方案,并且/或您已相应地重构复合材料以消除上述误用,则有两种可能的方法来应用客户端行为在复合材料部件上,取决于具体的功能要求(如果需要,您甚至可以将两种方式结合起来)。
如果您想让复合ajax渲染组件在之外复合,请将<p:ajax>
(或<f:ajax>
)外部化为<cc:clientBehavior>
:
<cc:interface>
<cc:clientBehavior name="myCustomEventName" targets="idOfTargetComponent" event="valueChange" />
...
</cc:interface>
<cc:implementation>
<h:selectOneMenu id="idOfTargetComponent" ...>
<f:selectItems ... />
</h:selectOneMenu>
</cc:implementation>
将用作:
<t:enum ...>
<p:ajax event="myCustomEventName" update=":absoluteClientIdOfComponentOUTSIDEComposite" />
</t:enum>
<x:someComponent id="idOfComponentOUTSIDEComposite" />
如果你想让复合ajax渲染一个组件 in 复合,那么让复合完成所有这些。
<cc:interface>
...
</cc:interface>
<cc:implementation>
<h:selectOneMenu ...>
<f:selectItems ... />
<p:ajax update="idOfComponentINSIDEComposite" />
</h:selectOneMenu>
<x:someComponent id="idOfComponentINSIDEComposite" />
</cc:implementation>
并以通常的方式使用它:
<t:enum ... />