我有一个面板,我用它来显示有关位置的信息。我有一个页面,我用它来显示涉及两个位置的交付预约的信息。 “我的传递”页面包括两次“位置面板” - 一次用于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的新手,所以如果这是一个愚蠢的问题,请继续关注
答案 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测试。