Wicket - 生成动态表 - ChildId警告

时间:2014-01-02 09:12:42

标签: java wicket

我正在尝试在wicket中创建一个动态表组件来显示一个对象列表。该组件将接收一个对象列表并以表格形式呈现它。

假设以下产品实体:

public class Product {
    public static final long serialVersionUID = 1L;
    //
    private String id; 
    private String name; 
    private String description; 
    private Double price; 
    // getters and setters omitted for brevity
}

以下html /代码对将起作用:
(注意:产品实体稍后将被通用化,因此我们可以将其传递给任何POJO的列表)

<table>
    <tbody>
        <tr wicket:id="row">
            <td wicket:id="cell">
                cell
            </td>
        </tr>
    </tbody>
</table>   
----------------------------------------------------------------
parameters: 
final String[] fieldNames = new String[]{"id", "name", "description", "price"};
List<Product> productList = .... 
----------------------------------------------------------------
ListView lvRows = new ListView("row", productList) {
    @Override
    protected void populateItem(ListItem item) {
        Product product = (Product)item.getModelObject(); 
        CompoundPropertyModel cpm = new CompoundPropertyModel(product);
        //
        RepeatingView cell = new RepeatingView("cell", cpm); 
        item.add(cell); 
        //                
        for (String fn : fieldNames) {                    
            Label label = new Label(fn); 
            cell.add(label); 
        }                
    }            
};
this.add(lvRows);

问题是上面的代码会导致一堆警告(列表中的每个产品都有一个警告):

  

00:57:52.339 [http-apr-8080-exec-108]警告   o.a.w.m.repeater.AbstractRepeater - 转发器的子组件   org.apache.wicket.markup.repeater.RepeatingView:cell有一个不安全的   id的子ID。安全的子ID必须仅由数字组成。

所以我的问题是:

  1. 我做错了吗?

  2. 如果没有,我如何摆脱警告?

  3. 为什么wicket在这个实例中需要数字子ID? CompoundPropertyModel在其他情况下工作正常,id链接到对象属性...

  4. 如果我做错了,那么“正确”的做法是什么?我应该唯一地创建子ID,使用CompoundPropertyModel放弃,并通过反射直接提供值吗?虽然不确定性能影响,但对每个单元格进行反射调用并不便宜。像这样:

    for(String fn:fieldNames}  {
      String s = ...; //find the value of Object O, property fn via Reflection
      Label label = new Label(cell.newChildId(), s);
      cell.add(label);
    }
    
  5. 提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以通过在RepeatingView中添加中间孩子来避免警告,正如Igor Vaynberg在Wicket用户列表this post中所解释的那样。

换句话说,不要将带有非数字ID的Label直接添加到转发器,而是添加带有数字ID的容器,并将Label添加到容器中:

RepeatingView cell = new RepeatingView("cell"); 
WebMarkupContainer container = new WebMarkupContainer(cell.newChildId(), cpm);
for (String fn : fieldNames) {                    
    Label label = new Label(fn); 
    container.add(label); 
}               
cell.add(container);
item.add(cell); 

这些警告的原因也在该帖中列出。

编辑

您似乎需要对ProductPanel进行建模,并在RepeatingView内使用,而不只是WebMarkupContainer。这意味着ProductPanel必须在其HTML中显式枚举属性(或wicket:id s)。

如果您希望HTML独立于特定属性,您也可以保留当前代码并执行Label label = new Label(cell.newChildId(), new PropertyModel(product, fn));并删除CPM。