Comment faire pour remplir les options de h:selectOneMenu à partir de la base de données?
Je suis entrain de créer une application web, où vous avez à lire une liste d'objets /entités à partir d'une base et de le remplir dans un JSF <h:selectOneMenu>
. Je suis incapable de code ce. Quelqu'un peut me montrer comment faire?
Je sais comment obtenir un List<User>
à partir de la DB. Ce que j'ai besoin de savoir, c'est comment remplir cette liste dans un <h:selectOneMenu>
.
<h:selectOneMenu value="#{bean.name}">
...?
</h:selectOneMenu>
InformationsquelleAutor Illep | 2011-07-27
Vous devez vous connecter pour publier un commentaire.
Basé sur votre question de l'histoire, vous êtes en utilisant JSF 2.x. Donc, voici de la JSF 2.x la réponse ciblée. Dans JSF 1.x vous seriez forcé d'envelopper les valeurs/les étiquettes dans laide
SelectItem
instances. Ce n'est heureusement pas besoin de plus de JSF 2.x.Exemple de base
Pour répondre directement à votre question, il suffit d'utiliser
<f:selectItems>
dontvalue
points pour unList<T>
propriété qui vous préserver de la DB au cours de l'haricot (post)de la construction. Voici une base de lancement pour exemple en supposant queT
représente en fait uneString
.avec
Simple que cela. En fait, la
T
'stoString()
sera utilisé pour représenter à la fois la liste déroulante de l'élément de l'étiquette et la valeur. Donc, quand vous êtes au lieu deList<String>
à l'aide d'une liste d'objets complexes commeList<SomeEntity>
et vous n'avez pas remplacé la classe'toString()
méthode, puiscom.example.SomeEntity@hashcode
comme élément de valeurs. Voir la section suivante comment le résoudre correctement.Également noter que le haricot pour
<f:selectItems>
valeur ne doit pas nécessairement être la même bean le bean pour<h:selectOneMenu>
valeur. Ceci est utile chaque fois que les valeurs sont en fait applicationwide constantes qui vous avez juste à charger qu'une seule fois au démarrage de l'application. Vous pouvez ensuite il suffit de faire une propriété d'une application étendue de haricot.Des objets complexes comme des éléments disponibles
Chaque fois que
T
concerne un objet complexe (javabean), commeUser
qui a unString
propriété dename
, alors vous pouvez utiliser lesvar
attribut de s'emparer de la variable d'itération qui vous peut utiliser dansitemValue
et/ouitemLabel
attribtues (si vous omettez leitemLabel
, l'étiquette devient la même que la valeur).Exemple #1:
avec
Ou quand il a un
Long
propriétéid
qui vous préférez définir comme la valeur de l'article:Exemple #2:
avec
Objet complexe comme élément sélectionné
Chaque fois que vous souhaitez définir une
T
propriété du bean ainsi etT
représente unUser
, alors vous devez faire cuire une coutumeConvertisseur
qui convertit entreUser
et une unique représentation de chaîne (qui peut être l'id
de la propriété). Notez que leitemValue
doit représenter l'objet complexe en lui-même, exactement le type qui doit être définie comme la sélection du composantvalue
.avec
et
(veuillez noter que le
Converter
est un peu hacky afin d'être en mesure d'injecter un@EJB
dans un JSF convertisseur; normalement, on aurait annoté comme@FacesConverter(forClass=User.class)
, mais qui, malheureusement, ne permet pas de@EJB
injections)N'oubliez pas de assurez-vous que l'objet complexe de classe a
equals()
ethashCode()
correctement mis en œuvre, sinon JSF sera pendant le rendu ne parviennent pas à montrer élément présélectionné(s), et vous aurez à soumettre visage Erreur de Validation: la Valeur n'est pas valide.Des objets complexes avec un convertisseur générique
Tête de cette réponse: Mettre en œuvre des convertisseurs pour les entités avec Java Génériques.
Objets complexes sans un convertisseur personnalisé
La JSF bibliothèque utilitaire OmniFaces propose un convertisseur spécial sorti de la boîte qui vous permet d'utiliser des objets complexes dans
<h:selectOneMenu>
sans la nécessité de créer un convertisseur personnalisé. LeSelectItemsConverter
va simplement faire la conversion, basé sur les articles facilement accessibles dans<f:selectItem(s)>
.Voir aussi:
<h:selectOneMenu>
de la page wikiAsk Question
de demander à claire et concrète à la question.@ManagedBean
par@Named
, etc. Ce n'est toujours pas exiger des changements dans la démonstration de classes et de méthodes.user
commeitemValue
à mon bean, dans mybean j'ai instancié unuser
afin de recevoir leuser
de la selectOneMenu, mais je ne pouvais pas le faire, rien ne se passe. Je pourrais le faire d'une autre manière, j'ai passé l'id
de lauser
à la fève puis n'utilisez Managed-BeannameService
àfind
lauser
, j'ai une question: puis-je comprendre queitemValue
ne peut que retourner primitive (en disant primitifs je veux dire les types inclus dans Java par défaut) les types commeString
etLong
et non à une autre Entité. s'il vous plaît corrigez-moi si je me trompe.ConverterUser
et une erreur de compilation a été généré, c'est dans cette ligne:throw new ConverterException(new FacesMessage(String.format("%s is not a valid User", modelValue)), e);
--> l'erreur est:cannot find symbol symbol: variable e..
. j'ai enlevé, e
et tout fonctionne bien. est-il ok pour supprimer la partie de code?user
, ne sommes-nous pas censés avoir quelque chose commeuser = new User()
être possible d'utiliser cet objet? si non, pourquoi?Vue-Page
Backing-Bean
Pour afficher particulière enregistrement sélectionné, il doit être l'une des valeurs dans la liste.
Rouler convertisseur générique pour des objets complexes comme élément sélectionné
La Balusc donne un très bon aperçu de réponse sur ce sujet. Mais il y a une alternative qu'il n'est pas présent: Le Roll-votre-propre convertisseur générique qui gère des objets complexes comme l'élément sélectionné. C'est très complexe à faire si vous voulez traiter l'ensemble des cas, mais assez simple pour les cas simples.
Le code ci-dessous contient un exemple de ce type de convertisseur. Il travaille dans le même esprit que la OmniFaces SelectItemsConverter qu'il regarde à travers les enfants, d'un composant pour
UISelectItem(s)
contenant des objets. La différence, c'est qu'il ne s'occupe que des liaisons simples collections d'objets de l'entité, ou les cordes. Il ne gère pas les groupes de produits, des collections deSelectItem
s, des ensembles et probablement beaucoup d'autres choses.Les entités que le composant se lie à doit mettre en œuvre les
IdObject
interface. (Cela pourrait être résolu d'une autre manière, comme l'utilisation detoString
.)Noter que les entités déclarantes sont tenues de mettre en œuvre
equals
de telle manière que les deux entités, avec le même ID compare l'égalité.La seule chose que vous devez faire pour l'utiliser, il est à spécifier que c'est le convertisseur sur l'sélectionner un composant, se lier à une entité de propriété et la liste des entités:
Converter:
Je fais comme ceci:
Modèles sont ViewScoped
converter:
et de se lier à un composant avec:
Si vous allez utiliser l'id de l'entité plutôt que de hashCode vous pouvez frapper une collision si vous avez quelques listes sur une seule page pour les différentes entités (classes) avec le même id
Appelez-moi paresseux, mais le codage d'un Convertisseur ressemble à beaucoup de travail inutile. Je suis l'aide de Primefaces et, n'ayant pas utilisé une plaine de vanille JSF2 zone de liste ou un menu déroulant avant, j'ai simplement supposé (paresseuse) que le widget pourrait manipuler des objets complexes, c'est à dire passer de l'objet sélectionné comme correspondant à son getter/setter, comme beaucoup d'autres widgets faire. J'ai été déçu de trouver (après des heures de casse-tête) que cette fonctionnalité n'existe pas pour ce type de widget sans Convertisseur. En fait, si vous fournissez un setter pour l'objet complexe plutôt que pour une Chaîne de caractères, il échoue silencieusement (il suffit de ne pas appeler le setter, pas d'Exception, pas d'erreur JS), et j'ai passé une tonne de temps va par le biais de BalusC excellent outil de dépannage pour trouver la cause, en vain, puisque aucune de ces suggestions appliquées. Ma conclusion: la zone de liste/menu widget besoins d'adaptation que d'autres JSF2 widgets ne le font pas. Cela semble induire en erreur et sujettes à la pointe du mal informés développeur comme moi, en bas d'un trou de lapin.
À la fin, j'ai résisté, le codage d'un Convertisseur et trouvé par essais et erreurs que si vous définissez la valeur d'un widget à un objet complexe, par exemple:
... lorsque l'utilisateur sélectionne un élément, le widget peut appeler une Chaîne de définition pour cet objet, par exemple
setSelectedThing(String thingString) {...}
, et la Chaîne de caractères passée est une Chaîne JSON représentant la Chose objet. Je peux l'analyser pour déterminer quel objet a été sélectionné. Cela se sent un peu comme un hack, mais moins d'un hack qu'un Convertisseur.h:inputText
ne pas trop si vous avez créé vos propres objets fortement typés au lieu d'utiliser une chaîne de caractères.h:inputText
, ou même ses plus sophistiqués frèrep:inputText
seulement de gérer les Chaînes de par leur nature. zone de liste/menu semble comme il devrait être capable de manipuler n'importe quel objet, même si bien sûr, cet objet ne peut être représenté par une Chaîne de caractères dans l'INTERFACE utilisateur.h:inputText
etp:inputText
peut traiter des nombres trop et de plus en plus. C'est parce que ce sont, sur la base des types java et convertisseurs sont fournis par jsf et implicitement appliqué. Pour tout autre type il a besoin d'un convertisseur de trop, par exemple personnalisé fortement typé GTIN, qui est effectivement un nombre (dans cette mise en œuvre, ils utilisent une Chaîne de caractères). Et oui, la conversion et de la "côté client" Chaîne de la représentation est ce que les convertisseurs de prendre soin de...