[英]JSF/Primefaces - ui:param in p:ajax element
我正在Java EE 6中编写应用程序,并使用Primefaces 3.4.1作为用户界面。
我有类似的东西。
genericPage.xhtml
<ui:composition template="mainApplicationTemplate.xhtml" [...]>
<p:tabView id="tabView" dynamic="false"cache="false">
<p:tab id="tab1" title="Tab 1">
<h:form id="form1">
...
</h:form>
</p:tab>
<p:tab id="tab1" title="Tab 1">
<h:form id="form2">
...
</h:form>
</p:tab>
</p:tabView>
<ui:composition >
child1.xmtml
<ui:composition template="genericPage.xhtml" ...>
<ui:param name="actionBean" value="#{actionBeanA}"/>
</ui:compisition>
child2.xmtml
<ui:composition template="genericPage.xhtml" ...>
<ui:param name="actionBean" value="#{actionBeanB}"/>
</ui:compisition>
其背后的想法是child1.xhtml和child2.xhtml共享相同的jsf代码,全部包含在genericPage.xhtml中,但它们有不同的后端bean(由“actionBean”参数化)
到目前为止,效果非常好。 当我将ui参数放在<p:ajax/>
元素中时,它会变得复杂。
从后端bean,我需要以编程方式更新活动选项卡,而保持另一个不变。 为此,我需要将活动选项卡存储在操作bean中。当发生某些外部事件时,操作bean会更新活动选项卡。
请注意,由于其他一些因素:
tabView
设置dynamic="true"
tabView
周围使用全局表单,因此不能使用'activeIndex'属性(我在应用程序的其他部分中执行)来管理活动选项卡。 要解决此问题,我想使用tabView
元素的tabChange
事件:
<p:tabView id="tabView" dynamic="false"cache="false">
<p:ajax event="tabChange" listener="#{actionBean.listen}"
<p:tab id="tab1" title="Tab 1">
<h:form id="form1">
...
</h:form>
</p:tab>
<p:tab id="tab1" title="Tab 1">
<h:form id="form2">
...
</h:form>
</p:tab>
</p:tabView>
动作豆
@Named
@WindowScoped
public class ActionBeanA implements Serializable{
public void listen(TabChangeEvent event){
...
}
}
当我这样做时,我收到了错误
Target Unreachable, identifier 'actionBean' resolved to null: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'actionBean' resolved to null
这似乎表明<p:ajax>
元素尚未传递给action bean,因此不知道actionBean
是什么。
但是,如果我像这样更改侦听器方法的签名
<p:ajax event="tabChange" listener="#{actionBean.listen(anything)}"
并将后端bean更改为:
public void listen(TabChangeEvent event){
System.out.println(event.toString());
}
这样做,我没有得到目标无法访问的错误,但在listen方法中是一个空指针异常(因为我还没有为“任何东西”赋值)。 这表明在这种情况下, <p:ajax/>
元素知道actionBean
是什么,并设法调用bean中的方法。
我怎么能解决这个问题? 我希望能够在标签更改事件中向我的后端bean发送新的活动标签。
我也遇到了这个问题,并在Primefaces问题跟踪器中找到了解决方案: 在#20的帖子中找到了解决方案
总而言之,这是Primefaces中的一个已知问题。 可以在3.4.2版中找到半修复程序,并且需要对代码进行一些更改。 目前你有:
public void listen(TabChangeEvent event){
System.out.println(event.toString());
}
哪个不起作用。 您应该将代码更改为:
public void listen(AjaxBehaviorEvent event){
System.out.println(event.toString());
}
如果你需要使用TabChangeEvent
特定方法,那么你需要进行转换: (TabChangeEvent)event
。
它在问题跟踪器上具有固定状态,因此可能需要将其作为永久解决方案。
值和方法表达式处理之间存在差异。 对于后者,您需要稍后使用参数 - 在Facelet上下文中。
要将参数的值包含在facelet上下文中,只需将参数值定义放在<f:metadata>
标记内。
另请注意, <f:metadata>
标记应始终是<f:view>
标记的直接子标记,因此我会执行以下操作:
的template.xhtml
<f:view ....>
<ui:insert name="metadata"/>
....
</f:view>
childPage.xhtml
<ui:composition template="/WEB-INF/template.xhtml">
<ui:define name="metadata">
<f:metadata>
<ui:param name="actionBean" value="#{actionBeanA}"
</f:metadata>
</ui:define>
</ui:composition>
执行此操作后,您可以使用原始方式的template.xhtml
的listener属性而不使用变通方法,并始终使用相应的事件类型参数调用您的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.