Калитка: Избегайте присвоения модели ListChoice модели формы - PullRequest
1 голос
/ 23 марта 2012

Играю с этим пару часов и, кажется, не могу понять это.

В Wicket, List Choice принимает список моделей, которые будут представлять варианты, которые составляют список. После отправки формы, к которой добавлен выбор списка, Wicket связывает модель выбранного выбора с моделью формы.

Но что, если я не хочу, чтобы вся модель была привязана, а вместо нее указывалось определенное свойство?

Например:

public class FormModel {
        private int locationId;

        public void setLocationId(int id) {
            this.locationId = id;
        }
    }

    public class LocationModel {
        private int id;

        public int getId() {
            return this.id;
        }
    }

    <select wicket:id="LocationId" id="LocationId" name="LocationId" size="1">
        <option value="#">#</option>
    </select>

Когда форма отправлена, Wicket попытается связать всю LocationModel с FormModel, где я просто хочу связать ее locationId свойство.

Я уже использую ChoiceRenderer, но, похоже, он работает только тогда, когда форма отображается, а не когда она отправлена.

Результатом является исключение приведения к окончательному классу, поскольку Wicket не сможет преобразовать LocationModel в целое число.

Я бы не хотел создавать другую модель специально для формы, принимающей LocationModel.

Есть мысли?

1 Ответ

5 голосов
/ 23 марта 2012

Объект Model объекта DropDownChoice (выбранное значение) всегда является одним из объектов в списке выбора.Таким образом, невозможно предоставить список вариантов, в которых элементы относятся к одному типу, и сохранить выборку в DropDownChoice Model в объекте другого типа (*).

Просто предоставьте List<Integer>.Если вы согласны с этим locationId как текстом <option>, IChoiceRenderer не понадобится.В противном случае ваш IChoiceRenderer должен получить описание с locationId, например, с вызовом вспомогательной функции getDescriptionForLocationId(Integer locationId).

Если реализация этой функции getDescriptionForLocationId будет дорогостоящей, можно использовать другой подход:

  1. Реализация пользовательского IModel, который получает Map<Integer, String> (или создаетво время getObject()) и в getObject() верните ключи от Map.Это предоставит List в качестве выбора DropDownChoice.
  2. Реализуйте метод getDescription() в своем пользовательском классе IModel, который запросит у Map описание Integer.
  3. В IChoiceRenderer найдите модель DropDownChoice и назовите ее getDescription(), чтобы получить правильное описание.

Вот небольшой пример: http://pastebin.com/DhKbsdQz

Обратите внимание на недостатки этого подхода: Map будет сериализован вместе с Model (он также может быть расширен LoadableDetachableModel для эффективности)

(*) Размышляя об этом, Wicket использует equals() за кулисами, чтобы установить соответствие между ModelObject объекта ddc и элементами в списке выбора, поэтому у него есть логика:

...