Wicket - 如何正确地重新加载/刷新可重用组件?

时间:2013-01-29 15:30:40

标签: ajax refresh wicket panel reusability

  1. 我有一个java类:

    public Task {
    
        private int id;
        private Company sender;
        private Company receiver;
    
        //Getter and Setter
        ...
    }
    

    如您所见,我在任务类中有2个其他自定义类。并且公司有例如Adress和Directory。

  2. 我有一个可以在页面上重复使用的CompanyPanel。以下是该小组的一些代码。

    public class CompanyPanel extends Panel {
    
        protected List<Company> companies;
    
        public CompanyPanel(String id, IModel<Company> model) {
    
        super(id,new CompoundPropertyModel<Company>(model));
        companies = new ArrayList<Company>();
    
        Company company_1 = new Company();
            //Setting default predefined values for the company, so I can select it from the dropdown and to set fields automatically
    
        company_1.setFtpAdress("adress1.com");
        company_1.setFtpDir("/MusterDir/");
        companies.add(company_1);
    
        //SAME for another company
                ...
        companies.add(comany_2);
                ...
    
        final DropDownChoice<Company> companyList = new DropDownChoice<Company>("companies", model,
            new LoadableDetachableModel<List<Company>>() {
        @Override
        protected List<Company> load() { 
            return companies;
        }
        }){
            protected boolean wantOnSelectionChangedNotifications() {
            return true;
            }
        };
        add(companyList);
    
        final TextField<String> ftpAdress = new TextField<String>("ftpAdress");
        ftpAdress.setOutputMarkupId(true);
        add(ftpAdress);
    
        final TextField<String> ftpDir = new TextField<String>("ftpDir");
        ftpDir.setOutputMarkupId(true);
        add(ftpDir);
    
         //added Ajax to dropdown to update textfields automatically, based on selection of dropdown
        companyList.add(new AjaxFormComponentUpdatingBehavior("onchange")
        {
        @Override
        protected void onUpdate(AjaxRequestTarget target)
        {
            target.add(ftpAdress);
            target.add(ftpDir);
        }
        });
      }
    }
    
  3. 在Page I中使用可重复使用的CompanyPanels。

    ...
    CompanyPanel senderPanel = new CompanyPanel("senderPanel", new PropertyModel(task,"sender"));
    senderPanel.setOutputMarkupId(true);
    form.add(senderPanel);
    
    CompanyPanel receiverPanel = new CompanyPanel("receiverPanel", new PropertyModel(task,"receiver"));
    receiverPanel.setOutputMarkupId(true);
    form.add(receiverPanel);
    ...
    
  4. 当我提交表格时,我会这样做:

    public void onSubmit(AjaxRequestTarget target, Form<?> form) {
    
        //doSomething
        target.add(senderPanel);
        target.add(receiverPanel);
    
    }
    
  5. 问题:公司面板没有被重新渲染。我真的不知道为什么。

    工作流:

    1. 我从下拉列表中选择了一家公司
    2. TextFields(位于companyPanel内)将根据下拉列表正确设置
    3. 我修改了textField(属于公司)
    4. 我提交表格
    5. 我从下拉列表中更改公司
    6. 我改回第一家公司 - &gt;问题:修改后的文本字段仍显示内部修改后的文本。它没有重置为默认值。
    7. 非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

当然,他们会显示修改后的值。您在CompanyPanel构造函数中创建公司列表。修改公司的数据时,将在该列表中修改对象。

解决此问题的一种快速方法是在onSubmit方法中将CompanyPanel面板替换为新的CompanyPanel实例。这将重新创建具有默认值的公司列表。您当然会丢失修改后的值。

另一个可能更好的解决方法是将公司列表创建移动到loadabledetachablemodel:

final DropDownChoice<Company> companyList = new DropDownChoice<Company>("companies", model,
    new LoadableDetachableModel<List<Company>>() {
@Override
protected List<Company> load() { 
    List<Company>companies = new ArrayList<Company>();

    Company company_1 = new Company();
    //Setting default predefined values for the company, so I can select it from the dropdown and to set fields automatically

    company_1.setFtpAdress("adress1.com");
    company_1.setFtpDir("/MusterDir/");
    companies.add(company_1);

//SAME for another company
        ...
    companies.add(comany_2);
        ...

    return companies;
}

这样,每个请求都会使用默认值重新创建公司列表。

确保在公司中实现正确的equals()和hashCode()方法,尽管DropDownChoice显示正确的选定元素 - 因为在这种情况下,模型中的对象和列表中的对象可能永远不会==

答案 1 :(得分:-1)

您必须提供更多代码。如果您正确提交以便模型更改,请尝试:

senderPanel.modelChanged();
receiverPanel.modelChanged();
target.add(senderPanel);
target.add(receiverPanel);