2012-08-14 82 views
1

我有一个复合组件:阶段监听器还没有被调用

<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。

回答

1

<f:phaseListener>beforePhase()afterPhase()方法实际上需要由UIViewRoot执行的#{cc}重新评估每次。 #{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"

+0

呃......我以为我正在这个生命周期的东西之上。是的,它的工作原理,它足够干净。感谢您的额外提示。这只是我一直在寻找的常数。 – 2012-08-15 00:52:42

+0

不客气。 – BalusC 2012-08-15 01:30:06