[OmniFaces utilities] The
subscribeToRequestComponentEvent()
method subscribes the given callback instance to the given component that get invoked only in the current request when the given component system event type is published on the given component. The difference with UIComponent#subscribeToEvent(Class, ComponentSystemEventListener)
is that this listener is request scoped instead of view scoped as component system event listeners are by default saved in JSF state and thus inherently view scoped.[OmniFaces utilities] The
unsubscribeFromComponentEvent()
method unsubscribes the given event listener on the given event from the given component. Normally, you would use UIComponent#unsubscribeFromEvent(Class, ComponentSystemEventListener)
for this, but this wouldn't work when executed inside ComponentSystemEventListener#processEvent(javax.faces.event.ComponentSystemEvent)
, as it would otherwise end up in a ConcurrentModificationException
while JSF is iterating over all system event listeners. The trick is to perform the unsubscribe during the after phase of the current request phase #subscribeToRequestAfterPhase(PhaseId, org.omnifaces.util.Callback.Void)
.Methods:
- subscribe the given callback instance to the given component (request scoped event listener)
- unsubscribe the given event listener on the given event from the given component
See also: Events#subscribeToRequestAfterPhase
Note: If the
flow is in Render Response phase then there is too late to unsubscribe.
Usage:
Let's
suppose that we are in the apply() method of a tag handler and we want
to listen (via a callback) the PostValidateEvent emitted by the parent component, without
saving this component system event listener in the JSF state. We can easily
accomplish this via Events#subscribeToRequestComponentEvent():
@Override
public void
apply(FaceletContext context, final UIComponent parent) throws IOException {
...
subscribeToRequestComponentEvent(parent,
PostValidateEvent.class, new
Callback.WithArgument<ComponentSystemEvent>() {
@Override
public void invoke(ComponentSystemEvent event) {
processTheEvent(event);
}
});
}
protected
void processTheEvent (ComponentSystemEvent event) {
UIComponent component = event.getComponent();
// do something here
...
}
Or, maybe
you need to use the UIComponent#subscribeToEvent(Class,
ComponentSystemEventListener) as below:
@FacesComponent(value
= MyComponent.COMPONENT_TYPE, createTag = true)
public class
MyComponent extends UIComponentBase implements ComponentSystemEventListener {
public static final String COMPONENT_FAMILY =
"...";
public static final String COMPONENT_TYPE =
"...";
@PostConstruct
public void mySubscribeToEvent() {
subscribeToEvent(PreValidateEvent.class,
this);
}
@Override
public void processEvent(ComponentSystemEvent
event) throws AbortProcessingException {
// do something here
}
...
}
...
}
Now, in
order to unsubscribe from the PreValidateEvent and avoid saving in JSF state this
component system event listener, you can explicitly invoke the Events#unsubscribeFromComponentEvent(), as
below:
@Override
public void processEvent(ComponentSystemEvent
event) throws AbortProcessingException {
Events.unsubscribeFromComponentEvent(event.getComponent(),
event.getClass(), this);
// do something here
}
Niciun comentariu :
Trimiteți un comentariu