Wicket 保持面板元素的标记ID唯一
我有一个面板,用来显示某个位置的信息。我有一个页面,用于显示涉及两个地点的交货预约信息。“我的传递”页面包含两次位置面板-一次用于起点,一次用于目的地。此示例已简化,因此位置只有一个名称属性 问题: 为这两个位置的名称(和其他属性)设置标记ID并保持其唯一性的最佳方法是什么Wicket 保持面板元素的标记ID唯一,wicket,Wicket,我有一个面板,用来显示某个位置的信息。我有一个页面,用于显示涉及两个地点的交货预约信息。“我的传递”页面包含两次位置面板-一次用于起点,一次用于目的地。此示例已简化,因此位置只有一个名称属性 问题: 为这两个位置的名称(和其他属性)设置标记ID并保持其唯一性的最佳方法是什么 示例代码 LocationPanel.java public class LocationPanel extends BasePanel { public LocationPanel(String id, Str
示例代码 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);
}
}
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);
}
}
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>
<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>
<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>
SetDeliveryAppointment.html
<html xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:panel>
<h3><span wicket:id="name">SAMPLE location</span></h3>
</wicket:panel>
</body>
</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>
<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>
目标是: 因此,我希望在生成的HTML中看到如下内容 最终HTML视图源目标
<html xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:panel>
<h3><span wicket:id="name">SAMPLE location</span></h3>
</wicket:panel>
</body>
</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>
<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>
松弛位置
DAL定位
奖金:
这确实是一个贯穿各领域的问题。理想情况下,我们希望每个Wicket组件都有一个唯一的ID,但我们希望它能够根据我们规定的规则进行预测。完美的解决方案将解决这一问题
免责声明:我是Wicket的新手,所以如果这是一个愚蠢的问题,请对我放松点你可以简单地调用
setMarkupId(“origin”)代码>和setMarkupId(“目的地”)代码>(我不记得是否必须在面板的每个实例上使用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);
}
}
使用JS时,不应使用#id(例如,在jQuery中使用相对选择器)或生成javascript片段,在其中传递component.getMarkupId()
关于selenium还不确定,最好使用wicket测试框架(它非常强大)。所以这里有一种方法可以实现。如果组件的父组件上的模型是
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");
}
}
}
}
在使用HTML类
和使用HTMLid
之间,始终需要权衡。在开发Wicket组件时,组件的最终目标应该是可重用性,不是吗?我个人的偏好是坚持使用类
,尤其是在相同页面上重用组件时。然后通过JS集成、CSS样式和Selenium测试依赖于它们的层次结构(尽可能不特定)。代码有什么问题?看起来对我来说是正确的。每个组件都可以通过层次结构进行唯一访问。第一个name
将具有路径delivery:origin:name
,第二个将是delivery:dest:name
。Wicket会自动生成唯一的html标记ID(用于javascript/etc)。@kan因为如果我让Wicket负责命名,我会得到
。我需要一个可靠的方法来为JS和可能的Selenium测试引用这些内容。我不完全确定我是否理解你的意思。你能提供代码示例吗?我会编辑我的问题,让它更清楚我在寻找什么。我已经编辑了我的答案,如果我正确地理解了你想要的,我认为它可以做到这一点。还会有两个元素的DOMid
为“name”吗?似乎您必须将id参数从构造函数传递到init(..)方法,以便可以使用id参数的concat和组件的wicket id调用标签上的setMarkupId和setOutputMarkupId。如果是这样,然后,您还必须这样做,因为每个其他属性都会导致一些代码爆炸。不,因为传递到面板的id
分别对应于父容器中的wicket:id
,在您的情况下,origin
和dest
,我发现我漏掉了origin(u name)的东西,你可以按照你说的concat的类似模式(或者使用cssClass,如果你的目标是能够选择它#origin.name
),也许我不熟悉你所指的相对选择器。唯一DOM ID的意义不在于它允许您精确定位对象,而不管对象在页面上的什么位置?然后,如果页面布局发生显著变化,您的CSS和JS将不会中断。更不用说DOMgetElementById
的性能优势了。这里的问题是wicket方法。您制作的每个wicket组件都应该是独立的、自包含的。你可以把它们放在任何你想要的地方,而不发生任何冲突。例如,现在您的页面上有一个交付。但是明天您需要在同一页面上构建它们的列表,更改这些ID
s并不是一件小事,不可能为它们提供固定字符串。wicket会自动为它们中的每一个生成唯一的ID。我不同意,而且我认为,与处理wicket自动生成的DOM ID的脆弱性所需的黑客相比,为适应多次交付而需要进行的任何更改都是微不足道的。@Snekse从wicket的角度来看,只需将WebMarkupContainer
替换为RepeatingView
,就可以了(当然,如果您没有使用您所要求的任何hack)。所以,如果我希望每个“名字”都有一个唯一的ID,但我希望它是可预测的——即使只是“名字1”、“名字2”等,当名字标签嵌入面板时,我该怎么做?考虑到看似随机的命名,依靠Wicket的自动命名不是一个选项。在一个页面上有两个面板,并且“名称”ID为“namef”和“name11”是不可接受的