我在不同会话的静态Hashmap中有一些wicket面板存储,我想做一些像某些面板通知地图,然后地图通知所有其他面板。 例如:
public class PanelMap{
private static Map<Long, List<MyPanel>> map = new HashMap<Long, List<MyPanel>>();
public static void subscribe(Long id, MyPanel panel){
if (!map.containsKey(id)){
map.put(id, new ArrayList<MyPanel>());
}
map.get(id).add(panel);
}
}
public static void notify(Long id, String notification){
if (map.containsKey(id)){
List<MyPanel> panels = map.get(id);
for(MyPanel panel : panels){
panel.newNotification(notification);
}
}
}
}
在Panel中,newNotification(字符串通知)我想向服务器发送请求并在浏览器中刷新我的面板。
public void String newNotification(String notification){
// do some business logic depends on notification
onMyRequest();
}
我在wicket行为源文件中进行了一些搜索,我在AbstractDefaultAjaxBehavior
找到了我试图在我的wicket面板中创建自己的onRequest方法,如下所示
private void onMyRequest(){
AjaxRequestTarget target = ((WebApplication)getApplication()).newAjaxRequestTarget(getPage());
target.add( _some_wicket_components_ );
RequestCycle.get().scheduleRequestHandlerAfterCurrent(target);
}
但我所做的只是Wicket Ajax Debug中的一些Ajax错误
Wicket.Ajax.Call.processComponent: Component with id _containerdiv_ was not found while trying to perform markup update.
ERROR: Cannot find element with id: _someComponentIdOnPanel_
(这些组件存在)
我如何将自己的请求发送到服务器(或者如何获得有效的AjaxRequestTarget来更新我的组件?)
更新:我需要会话间通信。
答案 0 :(得分:2)
要更新不同用户会话的面板,您显然无法使用当前的AjaxRequestTarget,因为这在某种程度上表示服务器与请求用户之间的单个通信,而另一个用户的浏览器无法知道。 (非常基本上说的)
您可以使用an AjaxSelfUpdatingTimerBehavior轮询更新。这将为每个用户定期生成新的AjaxRequestTarget,您可以使用它来附加更改的面板。这是一个非常基本和简单的实现,很可能会影响您的系统性能并产生相当多的流量。
另一种方法是使用类似Atmosphere的东西,它由Wicket-Atmosphere支持(快速启动可以找到here)并且在wicket-library.com有一些例子,但是这就是我所知道的。
答案 1 :(得分:1)
使用Wicket事件总线系统。了解&#34; Wicket活动基础设施&#34; free Wicket guide。
的章节首先,您需要创建一个类来封装通知和AjaxRequestTarget
,并使用事件基础结构传递它们。
private class Notification {
private String message;
private AjaxRequestTarget target;
... constructor, getters, setters...
}
然后想要重新启动事件的面板必须覆盖onEvent
方法,如下所示:
public void onEvent(IEvent<?> event) {
if (event.getPayload() instanceof Notification) {
Notification notification = (Notification) event.getPayload();
... do whatever you want before updating the panel ...
// Update the panel
notification.getTarget().add(this);
}
}
所有组件都会回放使用Wicket事件基础结构发送的所有事件。所以你可以使用像这样的方法从任何其他面板发送事件
protected void sendMessage(String message, AjaxRequestTarget target) {
send(getSession(), Broadcast.BREADTH, new Notification(message, target));
}
请记住,如果您想使用AJAX更新组件,则需要设置setOutputMarkupId(true)
。如果它是一个可以隐藏的组件,并且您希望使用AJAX使其可见,那么您需要设置setOutputMarkupPlaceholderTag(true)
。