[OmniFaces utilities] The
subscribeToViewEvent()
methods subscribes the given callback (serializable (in 2.1) /un-serializable (in 2.0) void without arguments/void with one argument) to the current view that get invoked every time when the given system event type is published on the current view.Method:
- using OmniFaces 2.1 serializable callback
- using OmniFaces 2.0 un-serializable callback
Note By OmniFaces implementation, the listened emitter of system events is the UIViewRoot, so use only system events types that can be emitted by the component tree's view root. OmniFaces relies on its org.omnifaces.eventlistener.DefaultViewEventListener, listed below:
public abstract class DefaultViewEventListener implements SystemEventListener {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
// NOOP
}
@Override
public boolean isListenerForSource(Object source) {
return source instanceof UIViewRoot;
}
}
Usage:
Before
calling the Events#subscribeToViewEvent()
methods, let's have a quick overview of how this methods works. As the post
title said, this method allows to subscribe the given callback to the current
view that get invoked every time when the given system event type is published
on the current view. So, we pass to this method the system event type to be
observed, and one of the following OmniFaces Callbacks (this becomes the
listener):
- using OmniFaces 2.1 serializable callback
- using OmniFaces 2.1 serializable callback
Basically, all we need to do is to subscribe to the desired event(s) with a Callback instance and implement a behavior to the corresponding invoke() method. Behind the scene, OmniFaces takes the provided Callback and creates a custom system event listener for it. When the specified event(s) occurs, OmniFaces will call our invoke() implementation. Knowing this, we can create a simple example:
JSF Page:
<h:form>
<o:outputLabel for="tomId"
value="Tom Enemy:"/>
<h:inputText id="tomId"
value="#{tomBean.enemy}"/>
<h:commandButton value="Get
Advice"/>
</h:form>
<h:outputText
rendered="#{facesContext.postback}"
value="#{tomBean.advice}"/>
TomBean
import
org.omnifaces.util.Callback;
import
static org.omnifaces.util.Events.subscribeToViewEvent;
...
@Named
@RequestScoped
public class
TomBean {
private String enemy;
private String advice;
@PostConstruct
public void adviceForTom() {
//the enemy value is not available in
@PostConstruct, but we can
//subscribe with a callback to
PreRenderViewEvent, when the enemy is available
//OmniFaces 2.0
// un-serializable void Callback
//OmniFaces 2.1
// serializable void Callback
// serializable void Callback
subscribeToViewEvent(PreRenderViewEvent.class, new Callback.SerializableVoid() {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
@Override
public void invoke() {
if (enemy != null) {
if (enemy.equals("jerry")) {
advice = "Tom, watch the dog while you are chasing Jerry!";
} else if (enemy.equals("dog")) {
advice = "Tom, be careful to Jerry traps!";
} else {
advice = "Tom, you have a new enemy ?!!";
}
}
}
});
//OmniFaces 2.0
// un-serializable void Callback
subscribeToViewEvent(PreRenderViewEvent.class, new
Callback.Void() {
@Override
public void invoke() {
if (enemy != null) {
if (enemy.equals("jerry")) {
advice = "Tom, watch the dog
while you are chasing Jerry!";
} else if
(enemy.equals("dog")) {
advice = "Tom, be careful to
Jerry traps!";
} else {
advice = "Tom, you have a new
enemy ?!!";
}
}
}
});
// serializable void Callback with argument
subscribeToViewEvent(PreRenderViewEvent.class, new
Callback.SerializableWithArgument<SystemEvent>() {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
@Override
public void
invoke(SystemEvent event) {
if
(enemy != null) {
if (enemy.equals("jerry")) {
advice = "Tom, watch the dog
while you are chasing Jerry!";
}
else if (enemy.equals("dog")) {
advice = "Tom, be careful to
Jerry traps!";
} else {
advice = "Tom, you have a new enemy ?!!";
}
}
}
});
//OmniFaces 2.0
// un-serializable void Callback with argument
subscribeToViewEvent(PreRenderViewEvent.class, new Callback.WithArgument<SystemEvent>() {
@Override
public void invoke(SystemEvent event) {
if (enemy != null) {
if (enemy.equals("jerry")) {
advice = "Tom, watch the dog while you are chasing Jerry!";
} else if (enemy.equals("dog")) {
advice = "Tom, be careful to Jerry traps!";
} else {
advice = "Tom, you have a new enemy ?!!";
}
}
}
});
...
When Tom
submits the form and the application flow reaches in the @PostConstruct method, the enemy value was
not set yet. But, we register a callback as a listener for the PreRenderViewEvent which means that right before the UIViewRoot is about to be rendered the invoke() method is called, and the enemy value is
set and can be used to choose the right advice for Tom. Nice!
Complete
code on GitHub