DropDownChoice получает повторяющиеся варианты

У меня проблема с компонентом DropDownChoice (DDC). Ситуация следующая: я хочу создать простую страницу реестра для конкурса. Поэтому мне нужна команда с участниками. Я создал форму (которая состоит из различных панелей / форм), в которой вы можете ввести имя, возраст и "положение в игре". Затем вы нажимаете кнопку "Добавить участника", и участник должен появиться в DropDownChoice.

Я новичок в Apache Wicket, и на самом деле я рад, что мне удалось показать форму на экране и увидеть, что участники действительно добавлены в DDC. Но тут возникает проблема: все участники DDC "превращаются" в последнего добавленного. Другими словами: предположим, я создаю участника Джефф. Джефф добавляется в DDC, нет проблем. Тогда я создаю Майка. Когда я добавляю Майка в DDC и смотрю на доступных участников, Джефф, кажется, превратился в Майка. Итак, на данный момент у меня есть 2 участника в моей команде, но первый, Джефф, я внезапно тоже Майк. И изменилось не только отображаемое свойство. Это полное содержимое объекта "Участник", которое превращается в Майка.

Теперь, если бы я хотел добавить Джанин, Джефф и Майк оба превратились бы в Джанин, и у меня было бы 3 "участника Джанина" в моем DDC. Я добавлю код "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() 

метод, который возвращает список участников. Модель, возвращаемая участником-участником (это пользовательский метод, передающий модель из формы на этой панели), верна. Возвращает участника, которого я ввел в мою форму. Но когда я просматриваю список команд, еще до того, как мой отладчик добирается до этой строки, я вижу, что все остальные участники уже "изменились". И я не касаюсь списка, только добавляю новых участников.

Есть хоть кто-нибудь? Спасибо! Если это было абсолютно не ясно, пожалуйста, спросите!

2 ответа

Решение

Каждый раз, когда вы добавляете нового участника, элемент ParticipantPanel должен повторно инициализировать свою модель, в противном случае его объект модели все время ссылается на один и тот же объект.

В деталях:

Участник а.

При первом рендеринге ваша панель использует этого участника, поэтому при добавлении он добавляет его в ваш список.

После этого во время повторного рендеринга объект модели панели все еще указывает на участника a. Так что изменения влияют на старый объект. Вот почему ваш выпадающий список повторяет ваш единственный участник.

Попробуйте следующее:

Вместо использования геттера используйте PropertyModel

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

изменить на

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

Укажите idExpression в ChoiceRenderer

new ChoiceRenderer<Participant>("firstname");

изменить на

new ChoiceRenderer<Participant>("firstname", "id");
Другие вопросы по тегам