1

我在来自不同会话的静态哈希图中存储了一些检票口面板,我想做一些事情,比如某个面板通知地图,然后地图通知所有其他面板。例如:

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);
            }
        }
    }
}

在面板中,newNotification(字符串通知)我想向服务器发送请求并在浏览器中刷新我的面板。

public void String newNotification(String notification){
   // do some business logic depends on notification
   onMyRequest();
}

我在检票口行为源文件中进行了一些搜索,关于我发现AbstractDefaultAjaxBehavior我试图在我的检票口面板中创建自己的 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 来更新我的组件?)

更新:我需要会话间通信。

4

2 回答 2

2

要更新不同用户会话上的面板,您显然不能使用当前的 AjaxRequestTarget,因为这在某种程度上代表了服务器和另一个用户的浏览器无法知道的请求用户之间的单一通信。(非常非常基本的口语)

您可以使用AjaxSelfUpdatingTimerBehavior来轮询更新。这将定期为每个用户生成新的 AjaxRequestTarget,您可以使用它来附加更改的面板。这是一个非常基本且简单的实现,很可能会影响您的系统性能并产生相当多的流量。

另一种方法是使用Atmosphere之类的东西,它由 Wicket-Atmosphere 支持(可以在此处找到快速入门),并且在wicket-library.com上有一些示例,但这就是我所知道的全部内容。

于 2013-07-01T11:10:35.463 回答
1

使用 Wicket 事件总线系统。查看免费 Wicket 指南的“Wicket 事件基础设施”一章。

首先,您需要创建一个类来封装通知并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).

于 2013-06-30T02:28:30.847 回答