Instances of this interface will handle specific types of
Actionclasses on the client.
When a command is executed (or undone), the
ClientActionHandler that
has been registered with the bound
ClientActionHandlerRegistry is
called and
com.gwtplatform.dispatch.shared.DispatchAsync does
not automatically send the command over gwt-rpc to the server.
Client Action Handlers provide a number of flexible options:
- The action can be modified before sending the action over gwt-rpc to the
server.
- A result can be returned without contacting the server.
- The result can be modified or processed after it is returned from the
server.
- The
ClientActionHandler can take over and communicate directly
with the server, possibly using a different mechanism than gwt-rpc.
Important! If your action handler makes asynchronous calls, be careful
with your use of fields as a second call your handler could be made while it
is waiting for the asynchronous call to return.
Caching Client Action Handler Example
// Interface of cache singleton
public interface Cache {
<A extends Action<R>, R extends Result> R get(A action);
<A extends Action<R>, R extends Result> void put(A action, R result);
}
// Client action handler that injects the cache
public class RetrieveFooClientActionHandler
extends
AbstractCachingClientActionHandler<RetrieveFooAction, RetrieveFooResult> {
@Inject
RetrieveFooClientActionHandler(
Cache cache) {
super(RetrieveFooAction.class, cache);
}
}
// abstract client action handler that:
// - first checks cache and returns result immediately if found in cache
// - executes command on server using gwt-rpc
// - saves result to cache before returning it
public abstract class AbstractCachingClientActionHandler<A extends Action<R>, R extends Result>
extends AbstractClientActionHandler<A, R> {
private final Cache cache;
public AbstractCachingClientActionHandler(
Class<A> actionType, Cache cache) {
super(actionType);
this.cache = cache;
}
@Override
public DispatchRequest execute(final A action, final AsyncCallback<R> resultCallback,
ExecuteCommand<A, R> executeCommand) {
R cacheResult = cache.get(action);
if (cacheResult != null) {
resultCallback.onSuccess(cacheResult);
return new CompletedDispatchRequest();
} else {
return executeCommand.execute(action, new AsyncCallback<R>() {
@Override
public void onSuccess(R result) {
if(!request.isCancelled()) {
cache.put(action, result);
resultCallback.onSuccess(result);
}
}
@Override
public void onFailure(Throwable caught) {
resultCallback.onFailure(caught);
}
});
}
}
@Override
public DispatchRequest undo(A action, R result, AsyncCallback<Void> callback,
ClientDispatchRequest request, UndoCommand<A, R> undoCommand) {
// do nothing
return new CompletedDispatchRequest();
}
}