我有一个块级元素,一个容器,当 all 隐藏其子Wicket元素(按钮)时,应该隐藏它。换句话说,如果任何子按钮可见,则容器应该是可见的。
如果有任何按钮,其中一个按钮始终可见,因此我使用该按钮来控制<wicket:enclosure>
的可见性,完全在HTML端处理所有这些。
现在,规格已经改变,因此按钮可以独立隐藏/可见,因此简单的外壳将不再起作用(我认为)。
我得到了类似的东西:
HTML:
<wicket:container wicket:id="downloadButtons">
<wicket:message key="download.foo.bar"/>:
<input type="button" wicket:id="excelDownloadButton" wicket:message="value:download.excel"/>
<input type="button" wicket:id="textDownloadButton" wicket:message="value:download.text"/>
<!-- etc ... -->
</wicket:container>
爪哇:
WebMarkupContainer container = new WebMarkupContainer("downloadButtons");
// ... add buttons to container ...
boolean showContainer = false;
Iterator<? extends Component> it = container.iterator();
while (it.hasNext()) {
if (it.next().isVisible()) {
showContainer = true;
break;
}
}
addOrReplace(container.setVisible(showContainer));
但Java方面现在有点冗长和丑陋,我在想可能有一种更清洁的方法来做同样的事情。在那儿?当它的子组件都不可见时,你能以某种方式“自动”隐藏容器(及其所有附加标记)吗?
(Wicket 1.4,如果重要的话。)
答案 0 :(得分:10)
如果您希望这可以重复使用,可以将其定义为IComponentConfigurationBehavior
(适用于wicket版本&gt; 1.4.16),您可以将其附加到任何容器,然后在{{1}中设置容器可见性行为方法:
onConfigure()
答案 1 :(得分:4)
如果任何子项可见,您可以覆盖容器的isVisible
方法返回true(像现在一样评估子可见性)。这不会大幅减少代码,但在我看来它会“更好”,因为确定可见性的代码将是它“属于”的位置。您可以将其设置为一个专门的容器类来进一步封装代码。
或者你可以继承EnclosureContainer并添加你需要的任何可见性逻辑。
注意:覆盖isVisible时......
[...]警告说这有一些陷阱:
每次请求多次调用,可能需要数十次,因此请保持计算结构的轻量化
此值应在渲染/响应边界内保持稳定。这意味着如果isVisible()在渲染按钮时返回true, 但是当单击该按钮返回false时,您将收到错误
答案 2 :(得分:0)
您也可以使用访客。
在我的情况下,我在Panel中有链接的容器。代码:
public abstract class MyPanel extends Panel
{
private final WebMarkupContainer webMarkupContainer;
public MyPanel(String id)
{
super(id);
webMarkupContainer = new WebMarkupContainer("customContainer")
{
@Override
protected void onBeforeRender()
{
super.onBeforeRender();
boolean visible = Boolean.TRUE.equals(checkVisibleLinks());
setVisible(visible);
}
};
AjaxLink myLink = new AjaxLink("myLink")
{
@Override
public void onClick(AjaxRequestTarget target)
{
//some action
}
};
webMarkupContainer.add(myLink);
}
private Boolean checkVisibleLinks()
{
return webMarkupContainer.visitChildren(AbstractLink.class, new IVisitor<AbstractLink, Boolean>()
{
@Override
public void component(AbstractLink link, IVisit<Boolean> visit)
{
if (link.isVisible())
{
visit.dontGoDeeper();
visit.stop(true);
}
}
});
}
}