JSF:与自定义事件

发布于 2024-12-04 18:08:33 字数 748 浏览 1 评论 0原文

我不知道是否可以使用 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 {
}

I can't figure out if it is possible to use custom events using f:event. The book by Ed Burns suggests to ad the @NamedEvent annotation to the Event class and to use:

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

but the event seems never to be instantiated.

From my point of view this makes sense, since the component does not know anything about the event, e.g. when to publish, so this might be useful for custom component authors only.

On the other hand, standard components should be able to publish the the event if derived from e.g. PostAddToViewEvent. Anyway, custom events seem to be never published by standard components.

Am I missing something? Is there a convenient way to use custom events with standard components?

Here is what I wanted to do:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ま柒月 2024-12-11 18:08:33

是的,你可以为此,你必须重写 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 event) 方法,否则它将调用组件类中的广播方法,该方法必须由开发人员重写

@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 event)方法,它将注册事件,并且如果getPhaseId()方法未被覆盖,它将通过MyEvent类中的getPhaseId()方法获取将触发的阶段devloper 那么它将在其注册的同一阶段触发

yes you can for this you have to override some method in jsf render or component class

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));
    }
}

but in MyEvent class you have to override some methods

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

which will define in which face this event will process (by default it is ANY_PHASE and event trigger in same phase in which it registered)

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

if you have appropiate listener it must return true
if you have appropiate listener for MyEvent then JSF will call that listener's processAction(ActionEvent event) method when it will trigger event, otherwise it will call broadcast method in component class which has to be override by developer

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

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

Even you can register any event by your own by using component queueEvent(FacesEvent event) method, it will regiester event and it get the phase in which it will trigger by getPhaseId() method in MyEvent class if getPhaseId() method is not overrided by devloper then it will trigger in same phase in which it registered

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文