#java #wicket
#java #калитка
Вопрос:
Я создал простую форму калитки с выпадающим списком, кнопкой отправки и двумя текстовыми полями, чтобы попробовать некоторую цепочку моделей. HTML:
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<meta charset="utf-8" />
<title>DropDownTest</title>
</head>
<body>
<form wicket:id="selectForm">
<select wicket:id="dropDown"></select>
<input type="submit" wicket:id="bt"/>
<input type="text" wicket:id="age"/>
<input type="text" wicket:id="name"/>
</form>
</body>
</html>
и код Java:
public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;
private class Person implements Serializable {
private int age;
private String name;
public Person(){};
public Person(int pAge, String pName) {
age = pAge;
name = pName;
}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
public List<Person> getPersons() {
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(34, "Hanna"));
persons.add(new Person(17, "Ivan"));
persons.add(new Person(64, "Carol"));
return persons;
}
private Form form;
private DropDownChoice<Person> dropDown;
public HomePage(final PageParameters parameters) {
super(parameters);
Model<Person> personModel = new Model<Person>();
dropDown = new DropDownChoice<Person>("dropDown", personModel, getPersons(),
new ChoiceRenderer<Person>("name"));
form = new Form("selectForm");
form.add(new TextField("name", new PropertyModel(personModel, "name")));
form.add(new TextField("age", new PropertyModel(personModel, "age")));
form.add(dropDown);
form.add(new Button("bt"));
add(form);
}
}
Выпадающий список и два текстовых поля используют одну и ту же модель (PersonModel), поэтому, когда пользователь выбирает пользователя из выпадающего списка и отправляет форму, нажимая кнопку, и страница перезагружается, два поля получают свои значения от пользователя, выбранного с помощью модели. Это работает так, как ожидалось, и я не получаю ошибок. Теперь, если я изменю порядок, в котором я добавляю компоненты в форму из этого (рабочего):
form.add(new TextField("name", new PropertyModel(personModel, "name")));
form.add(new TextField("age", new PropertyModel(personModel, "age")));
form.add(dropDown);
к этому (не работает)
form.add(dropDown);
form.add(new TextField("name", new PropertyModel(personModel, "name")));
form.add(new TextField("age", new PropertyModel(personModel, "age")));
Я получаю сообщение об ошибке при отправке формы:
Метод [public int com.asbjorntest.Домашняя страница $Person.getAge()]. Не удается преобразовать нулевое значение в примитивный класс: int для его установки в com.asbjorntest.Домашняя страница $Person @71460b93
Я понимаю, что ошибка возникает из-за того, что я отправляю текстовое поле «возраст» без какого-либо значения, и оно не может быть преобразовано в int в моем классе Person. Но почему эта ошибка возникает только в том случае, если я добавляю выпадающий список перед добавлением текстовых полей в код Java? Или, может быть, я должен спросить: почему этого НЕ происходит, когда я добавляю его после? Имеет ли значение порядок, в котором я добавляю компоненты в форму или на страницу в коде Java, или я здесь что-то полностью упускаю?
Заранее спасибо за любые ответы или подсказки!
Ответ №1:
Я думаю, что порядок в HTML
не имеет значения. Порядок в Java
может иметь значение, поскольку порядок компонентов определяет, как они проверяются.
Когда вы добавляете DropDownChoice
последнюю версию, значение null
age
from the TextField
будет переопределено значением, которое вы выбрали в раскрывающемся списке, и все работает нормально.
Если вы разместите свои компоненты наоборот, у age
вас будет null
(значение из TextField
, и вы получите свою ошибку.
Короче говоря: будьте осторожны, когда несколько компонентов редактируют одно и то же значение модели.
Ответ №2:
Насколько я помню, не рекомендуется делиться моделями между компонентами, и поэтому рекомендуется создавать новую для каждого компонента. Обратите внимание, что при создании personModel
изначально не привязан конкретный человек, я подозреваю, что он создается при добавлении на страницу. Таким образом, лицо модели равно нулю, когда текстовые поля создаются и добавляются в форму.
В общем, я бы порекомендовал вам что-то подобное:
public HomePage(final PageParameters parameters) {
super(parameters);
Person person = new Person();
form = new Form("selectForm");
dropDown = new DropDownChoice<Person>("dropDown", new Model<Person>(person), getPersons(), new ChoiceRenderer<Person>("name"));
form.add(dropDown);
// I think you can use person as first parameter, else use new Model<Person(person),
form.add(new TextField("name", new PropertyModel(person, "name")));
form.add(new TextField("age", new PropertyModel(person, "age")));
form.add(new Button("bt"));
add(form);
}
В любом случае, прошло довольно много времени с тех пор, как я использовал Wicket, поэтому я могу быть совершенно неправ: P
Комментарии:
1. Хорошо, спасибо за ответ! Я новичок в Wicket, и я следовал руководству / руководству от apache, где описано, что модели совместного использования могут использоваться для создания цепочки моделей, где модель-результат одного компонента (в моем случае выпадающего списка) может быть источником модели для другого компонента. Но я полагаю, что, как комментирует @RobAu, я должен быть осторожен с порядком из-за проблем с проверкой. С уважением!