Wicket:隐藏组件而不必添加其所有子组件
Wicket: hide a component without having to add all its children
我一直在 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 的无知,希望有人能告诉我一种方法,让我可以 "discard a component and all children"。
不要以为成本高
不可见组件不会执行很多方法,最重要的方法是onRender() 和onComponentTag()。模型不执行 getObject()。
从html代的角度可见成本为零。
附加信息:
https://ci.apache.org/projects/wicket/guide/7.x/guide/componentLifecycle.html
根据当前版本 7.5.0 检查我的知识
我认为组件(不可见)必须存在,这是正常的 Wicket 理念。隐形组件是轻量级的。
顺便说一句,我不确定您的 myDataObject 是 wicket 模型。
我同意文档中的建议:使用模型。
没有这样的代码会更清晰 'if' - 我不喜欢使用分支实例化 - 但使用正确的模型。
避免在构造函数中使用过多 "active" 代码,例如不获取值,让通过模型有条件地(惰性)获取。
捕获 Wicket 构造函数中抛出的异常是丑陋的。但是应用程序可以很好地捕获渲染阶段的异常。
最后,请记住,这是使组件隐藏的两种策略,一种是静态的,第二种是动态的:
https://ci.apache.org/projects/wicket/guide/7.x/guide/keepControl.html#keepControl_1
你可以大大改进你的代码,这样就不会那么痛苦了:)
这是使用 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"
构建一个漂亮的显示组件
Java
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-component-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"));
}
}
}
我现在没有时间尝试,但我很确定
} else{
myContainer.setVisible(false);
}
应该可以。
如果根本不渲染父组件,Wicket 不会抱怨子组件丢失。
我一直在 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 的无知,希望有人能告诉我一种方法,让我可以 "discard a component and all children"。
不要以为成本高
不可见组件不会执行很多方法,最重要的方法是onRender() 和onComponentTag()。模型不执行 getObject()。 从html代的角度可见成本为零。 附加信息: https://ci.apache.org/projects/wicket/guide/7.x/guide/componentLifecycle.html
根据当前版本 7.5.0 检查我的知识
我认为组件(不可见)必须存在,这是正常的 Wicket 理念。隐形组件是轻量级的。
顺便说一句,我不确定您的 myDataObject 是 wicket 模型。 我同意文档中的建议:使用模型。
没有这样的代码会更清晰 'if' - 我不喜欢使用分支实例化 - 但使用正确的模型。
避免在构造函数中使用过多 "active" 代码,例如不获取值,让通过模型有条件地(惰性)获取。 捕获 Wicket 构造函数中抛出的异常是丑陋的。但是应用程序可以很好地捕获渲染阶段的异常。
最后,请记住,这是使组件隐藏的两种策略,一种是静态的,第二种是动态的: https://ci.apache.org/projects/wicket/guide/7.x/guide/keepControl.html#keepControl_1
你可以大大改进你的代码,这样就不会那么痛苦了:)
这是使用 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"
Java
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-component-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"));
}
}
}
我现在没有时间尝试,但我很确定
} else{
myContainer.setVisible(false);
}
应该可以。 如果根本不渲染父组件,Wicket 不会抱怨子组件丢失。