読者です 読者をやめる 読者になる 読者になる

ListView で AjaxSelfUpdatingTimerBehavior

定期的に表示更新するリストを作ろうと思って、
AjaxSelfUpdatingTimerBehavior を直接 ListView に付与してしまうと、以下のエラーになる。

This component is a repeater and cannot be repainted via ajax directly.
Instead add its parent or another markup container higher in the hierarchy.


そして、IllegalArgumentException でAJAX で描画できなくなってしまう。

対処は、表示するListView を WebMarkupContainer で括り、括ったWebMarkupContainer に、AjaxSelfUpdatingTimerBehavior を仕掛けること。
ListView で表示するリストは描画時にリストを取得するように、
LoadableDetachableModel を使用すること。

WebMarkupContainer listcontainer = new WebMarkupContainer("listcontainer");
listcontainer.setOutputMarkupId(true);
IModel<List<Element>> listModel = new LoadableDetachableModel<List<Element>>(){
   @Override
   protected List<Element> load(){

      // TODO Element リストを返す
      :

   }
};
listcontainer.add(new ListView<Element>("listview"listModel){
   SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   @Override
   protected void populateItem(ListItem<Element> item){
      Element e = item.getModelObject();
      item.add(new Label("time", sf.format(b.time)));
      item.add(new Label("count", Integer.toString(b.count)));
   }
});
listcontainer.add(new AjaxSelfUpdatingTimerBehavior(Duration.milliseconds(60 * 1000)));
add(listcontainer);

=====
<table>
   <thead>
      <tr><th>time</th><th>count</th></tr>
   </thead>
   <tbody wicket:id="listcontainer">
      <tr wicket:id="listview">
         <td wicket:id="time">2015/04/15 00:12:34</td>
         <td wicket:id="count">1034</td>
      </tr>
   </tbody>
</table>