我有一个复合组件:
<cc:interface componentType="com.example.MyComponent">
<!-- ... -->
</cc:interface>
<cc:implementation>
<f:phaseListener binding="#{cc}"/>
<div id="#{cc.clientId}">
<!-- ... -->
</div>
</cc:implementation>
及其类:
@FacesComponent("com.example.MyComponent")
public class MyComponent extends UIOutput implements NamingContainer, PhaseListener
{
@Override
public String getFamily()
{
return "javax.faces.NamingContainer";
}
@Override
public PhaseId getPhaseId()
{
return PhaseId.ANY_PHASE;
}
@Override
public void beforePhase(PhaseEvent event)
{
// Do something ...
}
@Override
public void afterPhase(PhaseEvent event)
{
// Do something ...
}
}
在任何情况下,无论是完整页面加载还是部分页面加载,都不会调用 beforePhase(PhaseEvent)
和 afterPhase(PhaseEvent)
方法。
我在这里注意到这个错误:http://java.net/jira/browse/JAVASERVERFACES-1200 ,但似乎很久以前就已经修复了。
我在 Java 6u33 x64 上使用 GlassFish 3.1.2.2。
最佳答案
#{cc}
每次当 beforePhase()
时都会重新评估或afterPhase()
<f:phaseListener>
的方法实际上需要由UIViewRoot
执行。 #{cc}
目前 EL 范围内不可用。它仅在组件的范围内可用。
如果 binding
则工作正常在复合组件的构造函数中至少指向一个请求范围的变量,如下所示:
public MyComponent() {
FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("ccc", this);
}
与
<f:phaseListener binding="#{ccc}" />
当然,只有当您有多个这种类型的复合组件时,这种构造才会失败。
您最好寻找替代方法:摆脱 <f:phaseListener>
完全使用 UIViewRoot#addPhaseListener()
在复合组件的构造函数中:
public MyComponent() {
FacesContext.getCurrentInstance().getViewRoot().addPhaseListener(this);
}
<小时/>
与具体问题无关,更好地使用 UINamingContainer.COMPONENT_FAMILY
常量而不是硬编码 "javax.faces.NamingContainer"
.
关于java - 复合组件中的阶段监听器从未被调用过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11950103/