我正在使用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参数放在元素中时,它变得复杂了。
从后端bean中,我需要编程方式更新活动选项卡,而保留其他选项卡不受影响。为了做到这一点,我需要在action bean中存储活动选项卡。当发生某些外部事件时,action 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>
操作Bean
@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方法中却会出现空指针异常(因为我没有给“anything”赋值)。这表明在此情况下,<p:ajax/>
元素知道 actionBean
是什么,并成功调用了bean中的方法。
问题
我该如何解决这个问题?我想在选项卡更改事件上,将新活动选项卡发送到我的后端bean。
void listen(TabChangeEvent event)
方法中。只需保留该方法的签名并使用listener="#{actionBean.listen}"
,框架会自动为您传递事件。 - Elias Dorneleslistener="#{actionBean.listen}"
时,会出现“目标不可达”的错误。 - phoenix7360void listen(TabChangeEvent event)
。我所说的是在前端更改调用的签名:listener="#{actionBean.listen}"
和listener="#{actionBean.listen(something)}"
。我意识到我不应该自己传递事件,但由于似乎存在一个错误,我只是试图找到解决方法。 - phoenix7360