Основываясь на истории вопроса, вы используете JSF 2.x. Итак, вот целевой запрос JSF 2.x. В JSF 1.x вам придется переносить значения / метки элемента в уродливые экземпляры SelectItem
. Это, к счастью, больше не требуется в JSF 2.x.
Чтобы ответить на ваш вопрос напрямую, просто используйте value
указывает на свойство List
, которое вы сохраняете из БД во время построения столбца (столбца). Вот пример базового запуска, предполагающий, что T
фактически представляет String
.
с
@ManagedBean
@RequestScoped
public class Bean {
private String name;
private List names;
@EJB
private NameService nameService;
@PostConstruct
public void init() {
names = nameService.list();
}
// ... (getters, setters, etc)
}
Простой. Фактически, T
's toString()
будет использоваться для представления как ярлыка выпадающего элемента, так и значения. Итак, когда вы вместо List
используете список сложных объектов, таких как List
, и вы не переопределили метод класса toString()
, вы увидите com.example.SomeEntity@hashcode
как значения элемента. См. Следующий раздел, как правильно его решить.
Также обратите внимание, что bean для значения
необязательно должен быть одним и тем же компонентом, что и bean для значения
. Это полезно, когда значения фактически являются общими константами, которые вам просто нужно загружать только один раз во время запуска приложения. Тогда вы могли бы просто сделать это свойством компонента с областью приложения.
Всякий раз, когда T
относится к сложному объекту (javabean ), например User
, который имеет свойство String
в name
, тогда вы можете использовать атрибут var
для получения переменной итерации, которую вы, в свою очередь, можете использовать в itemValue
и / или itemLabel
] присваивает (если вы опускаете itemLabel
, тогда метка становится той же, что и значение).
Пример # 1:
с
private String userName;
private List users;
@EJB
private UserService userService;
@PostConstruct
public void init() {
users = userService.list();
}
// ... (getters, setters, etc)
Или когда у него есть свойство Long
, которое вы хотели бы задать как значение элемента:
Пример # 2:
с
private Long userId;
private List users;
// ... (the same as in previous bean example)
Всякий раз, когда вы хотите установить его в свойство T
в bean-а также, а T
представляет User
], вам нужно будет испечь пользовательский Converter
, который преобразует между User
и уникальным строковым представлением (которое может быть свойством id
). Обратите внимание, что itemValue
должен представлять сам сложный объект, именно тот тип, который необходимо установить в качестве компонента выделения value
.
с
private User user;
private List users;
// ... (the same as in previous bean example)
и
@ManagedBean
@RequestScoped
public class UserConverter implements Converter {
@EJB
private UserService userService;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return userService.find(Long.valueOf(submittedValue));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(String.format("%s is not a valid User ID", submittedValue)), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
if (modelValue == null) {
return "";
}
if (modelValue instanceof User) {
return String.valueOf(((User) modelValue).getId());
} else {
throw new ConverterException(new FacesMessage(String.format("%s is not a valid User", modelValue)), e);
}
}
}
(обратите внимание, что Converter
немного взломан, чтобы иметь возможность вставлять @EJB
в конвертер JSF, обычно он должен был бы аннотировать его как @FacesConverter(forClass=User.class)
, , но, к сожалению, не позволяет @EJB
инъекции )
Не забудьте убедиться, что класс сложного объекта имеет equals()
и hashCode()
должным образом реализованы , в противном случае JSF во время рендеринга не сможет отобразить предварительно выбранный элемент (ы), и вы отправите face Ошибка проверки: значение недействительно .
public class User {
private Long id;
@Override
public boolean equals(Object other) {
return (other != null && getClass() == other.getClass() && id != null)
? id.equals(((User) other).id)
: (other == this);
}
@Override
public int hashCode() {
return (id != null)
? (getClass().hashCode() + id.hashCode())
: super.hashCode();
}
}
Голосовать до этого ответа: Реализовывать преобразователи для объектов с Java Generics .
Библиотека утилиты JSF OmniFaces предлагает специальный конвертер из окна, который позволяет y ou использовать сложные объекты в
без необходимости создания настраиваемого конвертера. SelectItemsConverter
просто выполнит преобразование на основе легко доступных элементов в
.
Когда вы объявляете параметр int c
во втором func
, он затеняет глобальный c
, поэтому все дальнейшие изменения в рамках функции применяются только к локальному c
вместо глобального.