【问题标题】:Wicket - How to reload/refresh reusable components correctly?Wicket - 如何正确重新加载/刷新可重用组件?
【发布时间】:2013-01-13 05:33:31
【问题描述】:
  1. 我有一个 java 类:

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

    如您所见,我在任务类中还有另外 2 个自定义类。例如,公司有地址和目录。

  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. 在页面中,我使用可重复使用的 CompanyPanel。

    ...
    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);
    
    }
    

问题:公司面板没有被重新渲染。我真的不知道为什么。

工作流程:

  1. 我从下拉面板中选择了一家公司
  2. 将根据下拉菜单正确设置 TextFields(位于 companyPanel 内)
  3. 我修改了一个textField(属于一家公司)
  4. 我提交表单
  5. 我从下拉列表中更改公司
  6. 我改回第一家公司 -> 问题:修改后的文本字段仍显示修改后的文本。它未重置为默认值。

非常感谢任何帮助。

【问题讨论】:

  • 我看到您也将此面板添加到您的表单中。什么时候第一次显示页面,然后你可以看到这个面板?
  • 是否首先调用了 onSubmit 方法?如果有验证器触发,则调用 onError 方法。
  • 你在 CompanyPanel 做什么?
  • @hudi 是的,当页面加载时我可以看到所有的面板
  • @Nicktar onSubmit 方法首先被调用,是的,当用户点击按钮时

标签: ajax refresh wicket panel reusability


【解决方案1】:

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

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

另一个可能更好的解决方法是将公司列表创建移动到可加载的可拆卸模型中:

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;
}

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

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

【讨论】:

  • 谢谢。那行得通!顺便说一句,你怎么知道那种原则?你擅长 Wicket 模型,还是只是 java 经验?
  • 自 2006 年以来,我一直在与 wicket 合作开展几个重大项目。掌握模型概念是学习曲线的一部分。
【解决方案2】:

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

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

【讨论】:

  • 不需要这些调用。
猜你喜欢
  • 2013-03-29
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
相关资源
最近更新 更多