我在页面上添加了一个下拉组件。此下拉列表的目的是更改呈现的输入表单的类型。例如,不同的表单具有不同的必填字段,可编辑字段等。
public final class Test extends WebPage
{
CustomPanel currentPanel = new MeRequest("repeater",FormType.MIN);
public Test(PageParameters parameters)
{
add(currentPanel);
DropDownChoice ddc = new DropDownChoice("panel", new PropertyModel(this, "selected"), panels, choiceRenderer);
ddc.add(new AjaxFormComponentUpdatingBehavior("onchange") {
protected void onUpdate(AjaxRequestTarget target) {
System.out.println("changed");
currentPanel = new MeRequest("repeater",FormType.PRO);
target.add(currentPanel);
}
});
add(ddc);
}
我尝试了各种选项,结果有限。唯一真正成功的是更新模型,但我真正想做的是改变组件的行为方式。
对我所缺少的任何想法?
答案 0 :(得分:6)
1)如果您想将一个面板替换为另一个面板,您可以执行以下操作:
首先,您应该输出原始面板的标记ID:
currentPanel.setOutputMarkupId(true);
然后在ajax事件处理程序中编写类似的东西:
protected void onUpdate(AjaxRequestTarget target) {
CustomPanel newPanel = new MeRequest("repeater", FormType.PRO);
currentPanel.replaceWith(newPanel);
currentPanel = newPanel;
currentPanel.setOutputMarkupId(true);
target.addComponent(currentPanel);
}
在这种情况下,每次下拉选项更改时,您都会向页面添加新面板,并从页面中删除旧面板。
2)但我会提出一个与你的问题略有不同的方法。您应该将面板的构造逻辑移动到onBeforeRender()方法:
public class MeRequest extends Panel {
private FormType formType;
public MeRequest(String id, FormType formType) {
super(id);
this.formType = formType;
// don't forget to output the markup id of the panel
setOutputMarkupId(true);
// constructor without construction logic
}
protected void onBeforeRender() {
// create form and form components based on value of form type
switch (formType) {
case MIN:
// ...
break;
case PRO:
// ...
break;
}
// add form and form components to panel
addOrReplace(form);
form.add(field1);
form.add(field2);
// ...
super.onBeforeRender();
}
public void setFormType(FormType formType) {
this.formType = formType;
}
}
然后你将只能在ajax事件中更改面板的类型:
protected void onUpdate(AjaxRequestTarget target) {
currentPanel.setFormType(FormType.PRO);
target.addComponent(currentPanel);
}
因此我们重建原始面板而不重新创建它。