0

我对 DropDownChoice(DDC)组件有疑问。情况如下: 我想为一个比赛创建一个简单的注册页面。所以我需要一个有参与者的团队。我创建了一个表格(由不同的面板/表格组成),您可以在上面输入姓名、年龄和“在游戏中的位置”。然后按下“添加参与者”按钮,参与者应该出现在 DropDownChoice 中。

我是 Apache Wicket 的新手,实际上我很高兴我能在屏幕上显示表格并看到参与者实际上已添加到 DDC。但是问题来了:DDC 中的所有参与者都“变成”了最后一个添加的参与者。换句话说:假设我创建了参与者 Jeff。Jeff 被添加到 DDC,没问题。然后我创建迈克。当我将 Mike 添加到 DDC 并查看可用的参与者时,Jeff 似乎已经变成了 Mike。所以在这一点上,我的团队中确实有 2 名参与者,但第一个,杰夫,我突然间也有迈克。改变的不仅仅是显示的属性。变成 Mike 的是 Participant 对象的完整内容。

现在,如果我想添加 Janine,Jeff 和 Mike 都会变成 Janine,我的 DDC 中会有 3 个“Janine 参与者”。我将添加“TeamForm”的代码,我认为这是最相关的。如果需要,我可以添加更多代码。

    package com.tvh.tournamentregistry.form;

import com.tvh.tournamentregistry.model.Participant;
import com.tvh.tournamentregistry.model.Team;
import com.tvh.tournamentregistry.panel.ParticipantPanel;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;

public class TeamForm extends Form {

    public TeamForm(String id){
        super(id);

        final Team team = new Team();
        CompoundPropertyModel<Team> teamModel = new CompoundPropertyModel<Team>(team);
        setModel(teamModel);

        add(new TextField("name"));

        Model<Participant> participantModel = new Model<Participant>();
        ChoiceRenderer<Participant> teamViewRenderer = new ChoiceRenderer<Participant>("firstname");
        final DropDownChoice<Participant> teamView = new DropDownChoice<Participant>("players",participantModel, team.getPlayers(), teamViewRenderer){

            @Override
            protected boolean wantOnSelectionChangedNotifications() {
                return true; 
            }            
        };
        add(teamView);

        final ParticipantPanel participantPanel = new ParticipantPanel("participantpanel");
        add(participantPanel);

        Button addParticipant = new Button("addparticipant"){
            @Override
            public void onSubmit() {
                Participant participant = (Participant) participantPanel.getModel().getObject();
                team.getPlayers().add(participant);
                teamView.setChoices(team.getPlayers());
                teamView.render();
                participantPanel.clear();
            }
        };

        addParticipant.setDefaultFormProcessing(false);
        add(addParticipant);

    }

    @Override
    protected void onSubmit() {
        super.onSubmit(); //To change body of generated methods, choose Tools | Templates.
    }   
}

我已经调试了这个小应用程序,我看到的非常令人不安。我放了一个断点

Participant participant = (Participant) participantPanel.getModel().getObject();

添加 2 个参与者后,我可以看看

 team.getPlayers() 

返回参与者列表的方法。参与者面板返回的模型(这是一种自定义方法,从该面板中的表单传递模型)是正确的。它返回我在表单中输入的参与者。但是当我查看团队列表时,甚至在我的调试器到达那条线之前,我就可以看到所有其他参与者已经“改变”了。而且我没有触及列表,只是添加了新参与者。

有任何想法吗?谢谢!如果这绝对不清楚,请询问!

4

2 回答 2

0

每次添加新参与者时,ParticipantPanel 必须“重新初始化”其模型,否则其模型对象始终引用同一对象。

详细地:

参与者 A.

在第一次渲染时,您的面板使用此参与者,因此添加,它将它添加到您的列表中。

之后,在重新渲染时,面板的模型对象仍然指向参与者 a。因此更改会影响旧对象。这就是为什么您的下拉列表会重复您的单个参与者。

于 2013-04-30T11:53:11.670 回答
0

尝试以下操作:

不要使用 getter,而是使用 PropertyModel

new DropDownChoice<Participant>("players",participantModel, team.getPlayers(), teamViewRenderer)

改成

new DropDownChoice<Participant>("players",participantModel, new PropertyModel(team, "players"), teamViewRenderer)

在 ChoiceRenderer 中指定 idExpression

new ChoiceRenderer<Participant>("firstname");

改成

new ChoiceRenderer<Participant>("firstname", "id");
于 2013-04-30T12:54:27.503 回答