保持标记ID对于面板元素是唯一的

时间:2011-12-21 16:38:21

标签: wicket

我有一个面板,我用它来显示有关位置的信息。我有一个页面,我用它来显示涉及两个位置的交付预约的信息。 “我的传递”页面包括两次“位置面板” - 一次用于Origin,一次用于Destination。此示例已简化,因此Location只有一个Name属性。

问题:

为两个位置的名称(和其他属性)设置标记ID同时保持其唯一性的最佳方法是什么?


示例代码

LocationPanel.java

public class LocationPanel extends BasePanel {

    public LocationPanel(String id, String locCode) {
        super(id);
        init(locCode);
    }

    private void init(String locCode) {
        LocationInfo locModel = new LocationInfo(locCode + " Location");
        CompoundPropertyModel model = new CompoundPropertyModel(locModel);
        Label name = new Label("name");
        setDefaultModel(model);
        add(name);
    }
}

LocationPanel.html

<html xmlns:wicket="http://wicket.apache.org">
<body>
    <wicket:panel>
        <h3><span wicket:id="name">SAMPLE location</span></h3>
    </wicket:panel>
</body>
</html>

SetDeliveryAppointment.java

public class SetDeliveryAppointment extends BaseWebPage{

    public SetDeliveryAppointment(String id) {
        super(id);
        init();
    }

    private void init() {
        Panel origin = new RampLocationInformationPanel("origin", "LAX");
        Panel dest = new RampLocationInformationPanel("dest", "DAL");
        WebMarkupContainer delivery = new WebMarkupContainer("delivery");
        delivery.add(origin);
        delivery.add(dest);
        add(delivery);
    }
}

SetDeliveryAppointment.html

<html xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:extend>
    <wicket:container wicket:id="delivery">
        <div wicket:id="origin"></div>
        <div wicket:id="dest"></div>
    </wicket:container>
</wicket:extend>
</body>
</html>

目标:

所以我想在结果HTML中看到的内容如下

最终HTML查看来源目标

<html>
<body>
    <div id="origin">
        <!-- The exact id doesn't matter -->
        <!-- as long as 'origin' and 'name' are contained in it -->
        <h3><span id="origin_name">LAX location</span></h3>
    </div>
    <div id="dest">
        <h3><span id="dest_name">DAL location</span></h3>
    </div>
</body>
</html>

加成: 这确实是一个贯穿各领域的问题。理想情况下,我们希望每个Wicket组件都能获得一个唯一的ID,但我们希望它可以根据我们规定的规则进行预测。完美的解决方案将解决这个问题。

免责声明:我是Wicket的新手,所以如果这是一个愚蠢的问题,请继续关注

4 个答案:

答案 0 :(得分:2)

当你使用JS时,你不应该使用#id(例如在jQuery中使用相对选择器)或生成一个javascript片段,你将通过component.getMarkupId()

不确定硒,可能更好的是使用wicket测试框架(它非常强大)。

答案 1 :(得分:0)

您可以在面板的每个实例上调用setMarkupId("origin");setMarkupId("destination");(我不记得是否必须setOutputMarkupId();才能使其正常工作)。请记住,您必须在页面中处理ID的唯一性(但Wicket不会生成与'origin'或'destination'冲突的名称。)

编辑:解释一下如何做到这一点,我会这样写LocationPanel.java

public class LocationPanel extends BasePanel {

   public LocationPanel(String id, String locCode) {
    super(id);
    //sets the markupId to the wicket:id passed
    //you'll have to make sure you don't have the same wicket:id in the whole hierarchy
    //of your page though 
    setMarkupId(id);
    setOutputMarkupId(true);
    init(locCode);
   }

   private void init(String locCode) {
    LocationInfo locModel = new LocationInfo(locCode + " Location");
    CompoundPropertyModel model = new CompoundPropertyModel(locModel);
    Label name = new Label("name");
    setDefaultModel(model);
    add(name);
  }
}

答案 2 :(得分:0)

所以这是一种可以实现的方法。如果组件父级上的模型是instanceof CompoundPropertyModel,则该父组件的Id可用于更改子组件的标记ID。

public class ComponentMarkupListener implements IComponentOnBeforeRenderListener {
  public void onBeforeRender(Component component) {
    if (component instanceof WebMarkupContainer || component instanceof Label) {
        component.setOutputMarkupId(true);

        if((component.getParent().getDefaultModel()) instanceof CompoundPropertyModel ){
          component.setMarkupId(component.getParent().getId()
              +"_"+ component.getId() + "_ID");
        }else{
          component.setMarkupId(component.getId() + "_ID");
        }
    }
  }
}

答案 3 :(得分:0)

在使用HTML class和使用HTML id之间始终需要权衡。在开发Wicket组件时,组件应该具有可重用性的最终目标,如果不是的话?我个人的偏好是坚持class,特别是如果在同一页面上重复使用组件。然后你依靠他们的层次结构(尽可能不具体)与JS集成,CSS样式和Selenium测试。