I have a Wicket component which is listening for some event (IEvent
). If such event arrives, I want to re-render the component with a changed model. There are no active controls on the page, like AjaxLink
, which can trigger the re-rendering.
Is there a way to refresh such kind of component?
I was thinking to somehow trigger an AJAX request from the onEvent
method and add an AjaxBehavior
to the mentioned component. But I don't know, how to trigger the AJAX request.
public class PersonPanel extends Panel implements Observer {
private WebMarkupContainer wrapper;
public PersonPanel(String id) {
super(id);
setDefaultModel(new CompoundPropertyModel<PersonInfo>(getModel()));
wrapper = new WebMarkupContainer("wrapper");
wrapper.setOutputMarkupId(true);
add(wrapper);
wrapper.add(new Label("personID"));
// some more content
}
private IModel<PersonInfo> getModel() {
return new LoadableDetachableModel<PersonInfo>() {
@Override
protected PersonInfo load() {
// model loading logic
}
};
}
@Override
public void onEvent(IEvent<?> event) {
logger.debug("\n Person Panel received an Event: " + event.getPayload());
// Re-rendering of "wrapper" should be triggered from here.
}
@Override
public void update(Observable observable, Object o) {
send(this, Broadcast.EXACT, "Observable cache has changed.");
}
}
Here is the solution, thanks to hint from martin-g, solved via WebSockets. See the methods update
and onEvent
, plus added WebSocketBehavior
on the component:
public class PersonPanel extends Panel implements Observer {
private WebMarkupContainer wrapper;
public PersonPanel(String id) {
super(id);
setDefaultModel(new CompoundPropertyModel<PersonInfo>(getModel()));
wrapper = new WebMarkupContainer("wrapper");
wrapper.setOutputMarkupId(true);
add(wrapper);
wrapper.add(new Label("personID"));
// some more content
add(new WebSocketBehavior() {
});
observableCache.addObserver(this);
}
private IModel<PersonInfo> getModel() {
return new LoadableDetachableModel<PersonInfo>() {
@Override
protected PersonInfo load() {
// model loading logic
}
};
}
@Override
public void onEvent(IEvent<?> event) {
if (event.getPayload() instanceof WebSocketPushPayload) {
WebSocketPushPayload wsEvent = (WebSocketPushPayload) event.getPayload();
wsEvent.getHandler().add(wrapper);
}
}
@Override
public void update(Observable observable, Object o) {
WebSocketSettings webSocketSettings =
WebSocketSettings.Holder.get(getApplication());
WebSocketPushBroadcaster broadcaster =
new WebSocketPushBroadcaster(webSocketSettings.getConnectionRegistry());
broadcaster.broadcastAll(
getApplication(),
new WebSocketMessage("WebSocket message from the PersonPanel."));
}
}
You can find a full running example project, implemented in Wicket 8 and Gradle on Bitbucket: