我一直在Wicket做一个项目,我经常发现自己陷入了困境。让我们说我有一个标记,我只在某些条件适用时显示,如下例所示:
<div wicket:id="myContainer">
<div wicket:id="label1"></div>
<div wicket:id="label2"></div>
<div wicket:id="label3"></div>
<div wicket:id="label4"></div>
</div>
并在我的Java代码中:
WebMarkupContainer myContainer = new WebMarkupContainer("myContainer");
add(myContainer);
if(myDataObject != null){
myContainer.add(new Label("label1", myDataObject.getData1());
myContainer.add(new Label("label2", myDataObject.getData2());
myContainer.add(new Label("label3", myDataObject.getData3());
myContainer.add(new Label("label4", myDataObject.getData4());
} else{
//HAVING TO DO THIS IS ABSURD!
myContainer.add(new Label("label1", "");
myContainer.add(new Label("label2", "");
myContainer.add(new Label("label3", "");
myContainer.add(new Label("label4", "");
myContainer.setVisible(false);
}
正如你所看到的,即使在我不打算显示它的情况下,我也不得不在容器中添加虚拟组件,否则Wicket会抛出异常,说我在标记中有组件我没有在代码中添加。
对我而言,这是荒谬的,必须实例化我将不会显示的额外组件是浪费,耗时并且使代码不必要地可读。
我希望这只是我对Wicket的无知,并且有人可以告诉我一种允许我放弃一个组件和所有孩子的方法。
答案 0 :(得分:5)
你可以改进你的代码很多,所以它变得不那么痛苦了:)
这是使用CompoundPropertyModel的好地方。
此外,只需控制容器的onConfigure()
中的可见性。
WebMarkupContainer myContainer = new WebMarkupContainer("myContainer", new CompoundPropertyModel(myDataObject))
{
public void onConfigure()
{
setVisible( this.getModelObject() != null);
}
}
add(myContainer);
myContainer.add(new Label("data1"));
myContainer.add(new Label("data2"));
myContainer.add(new Label("data3"));
myContainer.add(new Label("data4"));
您使用WebMarkupContainer
的方式建议您也可以使用Panel
为此“myDataObject”构建一个漂亮的显示组件
<强>爪哇强>
public class MyDataObjectPanel extends Panel
{
public MyDataObjectPanel(String id, IModel<MyDataObject> myDataObjectModel)
{
super(id, new CompoundPropertyModel(myDataObjectModel);
this.add(new Label("data1"));
this.add(new Label("data2"));
this.add(new Label("data3"));
this.add(new Label("data4"));
}
public void onConfigure()
{
setVisible( this.getModelObject() != null);
}
}
<强> HTML 强>
<wicket:panel>
<div wicket:id="data1"></div>
<div wicket:id="data2"></div>
<div wicket:id="data3"></div>
<div wicket:id="data4"></div>
</wicket:panel>
然后,您想要显示它的所有地方,只需使用此面板。
<小时/> 我会建议反对这个(因为它会让你的代码变得更复杂,我认为你不会赢得很多性能),但如果你真的不关心不向wicket组件添加元素-tree,你可以下一个代码。它决定是否显示专用组件,替换实际组件:
public class MainComponent {
@Override
protected void onConfigure()
{
MyDataObject obj = getDataObjectFromSomeModel();
if (obj == null) {
this.addOrReplace( new EmptyPanel("dataPanelId").setVisible(false));
}
else {
this.addOrReplace( new MyDataObjectPanel("dataPanelId"));
}
}
}
答案 1 :(得分:3)
我现在没有时间尝试,但我很确定
} else{
myContainer.setVisible(false);
}
应该有效。 如果父组件根本没有渲染,Wicket不会抱怨孩子丢失了。
答案 2 :(得分:2)
不要认为成本很高。
不可见组件不执行许多方法,最重要的方法是onRender()和onComponentTag()。模型不执行getObject()。 从html生成的角度看,可见成本为零。 附加信息: https://ci.apache.org/projects/wicket/guide/7.x/guide/componentLifecycle.html
根据当前版本7.5.0检查我的知识
我认为组件(隐形)必须存在,这是正常的Wicket哲学。隐形组件很轻巧。
BTW我不确定你的myDataObject是wicket模型。 我同意doc中的建议:使用模型。
代码将更清晰,没有这样的'if' - 我更喜欢不使用分支实例化 - 但是使用正确的模型。
在构造函数中避免使用太多“活动”代码,例如,不要获取值,让我们通过Model获取有条件(延迟)。 捕获Wicket构造函数中抛出的异常是很难看的。但是应用程序可以很好地捕获渲染阶段的异常。
最后,请记住,这些是隐藏组件的两个策略,一个是静态的,另一个是动态的: https://ci.apache.org/projects/wicket/guide/7.x/guide/keepControl.html#keepControl_1