JSF:带有自定义事件的<f:event> </f:event>

时间:2011-09-14 08:42:46

标签: jsf jsf-2 event-handling

我无法弄清楚是否可以使用f:event来使用自定义事件。 Ed Burns的书建议将@NamedEvent注释添加到Event类并使用:

<f:event type="com.foo.bar.myEvent" listener="#{listener} />

但事件似乎永远不会被实例化。

从我的观点来看,这是有道理的,因为该组件对事件一无所知,例如:什么时候发布,所以这可能只对自定义组件作者有用。

另一方面,标准组件应该能够发布事件,如果派生自例如PostAddToViewEvent。无论如何,自定义事件似乎永远不会被标准组件发布。

我错过了什么吗?有没有一种方便的方法来使用标准组件的自定义事件?

这就是我想要做的事情:

<h:inputText id="input">
    <f:event type="foo.bar.MyCustomEvent" /> 
</h:inputText>
public class MyCustomEvent extends javax.faces.event.PostAddToViewEvent {
}

1 个答案:

答案 0 :(得分:0)

是的,你可以为此你必须覆盖jsf渲染或组件类

中的某些方法
public class MyComponent extends HtmlInputText       or   public class MyRenderer extends TextRenderer

@Override
public void decode(FacesContext context, UIComponent component) {
    super.decode(context, component);

    String sourceName = context.getExternalContext().getRequestParameterMap().get("javax.faces.source");
    if(sourceName != null && sourceName.equals(component.getClientId())){
        component.queueEvent(new MyEvent(component));
    }
}

但是在MyEvent类中你必须覆盖一些方法

@Override
public PhaseId getPhaseId() {
    return PhaseId.INVOKE_APPLICATION;
}

将定义此事件将在哪个面处理(默认情况下,它是在注册的同一阶段中的ANY_PHASE和事件触发器)

@Override
public boolean isAppropriateListener(FacesListener listener) {
    return false;
}

如果你有合适的监听器,它必须返回true 如果你有适当的MyEvent监听器,那么JSF会在触发事件时调用该监听器的processAction(ActionEvent事件)方法,否则它将调用组件类中的广播方法,该方法必须被开发人员覆盖

@Override
public void broadcast(FacesEvent event) throws AbortProcessingException {
    super.broadcast(event);

    if(event instanceof MyEvent){
        try {
            processMyEvent(event);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

即使您可以使用组件queueEvent(FacesEvent事件)方法自己注册任何事件,它也将是regiester事件,并且如果getPhaseId()方法是,它将在MyEvent类中通过getPhaseId()方法触发它的阶段。没有被devloper覆盖,那么它将在它注册的同一阶段触发