2017-10-03 1 views
0

J'essaie de développer un sélecteur de données réutilisable. Il sera utilisé pour rechercher des données associées et définir dans la propriété bean géré.Composant sélecteur de données dans JSF

Ce que je suis en train de archieve est quelque chose comme ceci:

1) composite avec un texte d'entrée et bouton de recherche:

enter image description here

2) Lorsque l'utilisateur clique sur le bouton de recherche, ça ouvre une nouvelle page.

3) Cette page permet de rechercher un enregistrement spécifique

4) Une fois trouvé, l'utilisateur clique sur un bouton et le choisit

enter image description here

5) Lorsque l'utilisateur clique sur contrôle bouton (dernière colonne dans le tableau ci-dessus), il définit la valeur dans le champ lié à l'entrée (# 1).

La recherche est toujours effectuée dans la même entité car il s'agit d'un sélecteur de données pour une telle entité mais la destination n'est pas connue car il s'agit d'un composant réutilisable.

Comment établir une connexion entre les résultats de la recherche, ce que l'utilisateur choisit et l'objet de destination (qui est la propriété d'un bean géré)?

Je ne sais pas comment procéder.

Merci à l'avance,

EDIT

PLUS D'INFO: Après quelques recherches, j'ai trouvé un moyen de passer et de la propriété gérée par le bean/actionListener. Je vais expliquer ce que j'ai fait et décrire plus tard quel est le problème maintenant.

1) Création d'un exemple de page (sample1.xhtml). Il est une composition/fragment:

<?xml version='1.0' encoding='UTF-8' ?> 
    <!DOCTYPE html> 
    <ui:fragment xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:c="http://java.sun.com/jsp/jstl/core" 
     xmlns:b="http://bootsfaces.net/ui" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:p="http://primefaces.org/ui" 
     xmlns:bt="http://xmlns.jcp.org/jsf/composite/tags/bt" 
     xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"> 

     <ui:composition template="/templates/pages/form.xhtml"> 
      <ui:param name="title" value="Manage Value Object Category" /> 
      <ui:define name="toolbar"> 
      </ui:define> 
      <ui:define name="form-fields"> 
       <c:set var="variable" value="#{valueObjectBean}" scope="request" /> 
       <p:commandButton actionListener="#{valueObjectBean.doTest()}" 
        value="test" update="@form" /> 
      </ui:define> 
      <ui:define name="bar-cmd"> 
      </ui:define> 
     </ui:composition> 

    </ui:fragment> 

S'il vous plaît noter:

a) c: ensembles fixés à une demande variable de la scope pour appeler bean géré.

b) valueObjectBean.doTest() remplace simplement la composition à afficher.

2) Ceci est la page de destination:

  <?xml version='1.0' encoding='UTF-8' ?> 
    <!DOCTYPE html> 
    <ui:fragment xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:c="http://java.sun.com/jsp/jstl/core" 
     xmlns:b="http://bootsfaces.net/ui" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:p="http://primefaces.org/ui" 
     xmlns:bt="http://xmlns.jcp.org/jsf/composite/tags/bt" 
     xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"> 

     <ui:composition template="/templates/pages/form.xhtml"> 
      <ui:param name="title" value="Manage Value Object Category" /> 
      <ui:define name="toolbar"> 
      </ui:define> 
      <ui:define name="form-fields"> 
       <h:outputText value="Hello: #{variable}" /> 
       <p:commandButton id="call" actionListener="#{variable['doTest'](null)}" 
        value="Execute" /> 

       <p:commandButton id="set" value="Set"> 
        <f:setPropertyActionListener value="true" 
         target="#{variable['actAddCatItem']}"></f:setPropertyActionListener> 
       </p:commandButton> 
      </ui:define> 
      <ui:define name="bar-cmd"> 
      </ui:define> 
     </ui:composition> 

    </ui:fragment> 

S'il vous plaît noter:

a) commandButton avec id "appel" appelle un écouteur d'action de managed bean définie dans # 1a: {variable » doTest '}. Appelez la méthode 'doTest' de managedBean passée en variable à 'variable'.

b) Juste pour mentionner mais ce n'est pas important maintenant. Un autre commandButton avec l'ID "set" définit simplement une propriété à l'ensemble de bean géré dans # 1a. Je ne vais pas explorer cette option pour le moment.

Maintenant, ce qui se passe:

1) Lorsque # c: ensemble est demande scope (portée = "demande"), deuxième page "voit" le bean géré passé en paramètre:

enter image description here

a) Comme vous pouvez le voir, il sort toString de haricot géré mais quand je clique sur le bouton de commande avec id « appel », je reçois cette erreur:

16:59:24,901 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (default task-39) /WEB-INF/lib/infra-wm-1.0.jar/META-INF/resources/infra/valueobject/sample2.xhtml @24,44 target="#{variable['actAddCatItem']}": Target Unreachable, identifier 'variable' resolved to null: javax.el.PropertyNotFoundException: /WEB-INF/lib/infra-wm-1.0.jar/META-INF/resources/infra/valueobject/sample2.xhtml @24,44 target="#{variable['actAddCatItem']}": Target Unreachable, identifier 'variable' resolved to null 

Si je change c: set scope en 'view', cette approche fonctionne bien. Mais je ne peux pas utiliser cette portée car il pourrait y avoir plus d'un composite utilisant la même approche dans la page (à la fin c'est un composant composite). La question maintenant est: Pourquoi l'échantillon 2 reconnaît 'variable' quand c'est la portée de vue et non quand c'est la portée de la demande malgré que la valeur soit passée correctement et qu'elle ne soit pas NULL?

Merci,

+0

Essayez sans composite d'abord ... – Kukeltje

+0

Bonjour encore @Kukeltje! Merci de votre aide! En fait, sans un composite, c'est simple car je peux redéfinir la valeur choisie sur la page de l'appelant. Ce que j'essaye de faire est une sorte de "sélecteur de données" où j'ajoute ce composant à une page et cela ajoutera la fonction de recherche et de sélection. Je veux dire, une fois que l'utilisateur sélectionne, il définit la valeur sélectionnée à partir des résultats de recherche à l'attribut "valeur" comme vous pouvez le voir dans # 1. –

+0

Mais regardez, je voudrais créer un sélecteur générique et il ne sait pas où redéfinir la valeur sélectionnée, jusqu'à ce que le développeur le place dans l'attribut de valeur de composite. Je sais qu'il n'y a aucun moyen de passer des attributs par référence en raison de la nature des haricots gérés, alors quel est le prochain essai que je devrais faire? –

Répondre

0

Après quelques recherches, j'ai renoncé de cette approche et a fait ce que je voulais accomplir grâce à la boîte de dialogue modale Primeface mais je n'étais pas satisfait parce que les boîtes de dialogue modales ne fonctionne pas bien sur les appareils mobiles , spécialement quand vous avez besoin d'ouvrir un dialogue sur un dialogue. Mais le problème a été résolu, au moins pour la version un.

Maintenant, je suis retourné à défier et a fait une autre approche qui, finalement, a très bien fonctionné.

1) Trouver un moyen de passer et de se lier d'un haricot géré composite à un autre

Il a échoué parce que la liaison de actionListener commandButton est évaluée au cours du temps et rendre toujours eu NULL. J'ai demandé et développé des pensées finales ici: Question

Solution:

lecture des articles, des questions, je suis arrivé réponse finale à toutes mes questions: Utiliser la liaison commandButton instancier programme composant, définissez actionListener et mis en valeur sélectionnée à l'entité qui a initialement fait la recherche. Description est basé sur mon premier post:

1) La modification de recherche commandLink est un composite simple (# 1)

1.1) Interface composite a tous les attributs nécessaires à sa configuration, plus importants sont:

  • L'attribut de valeur lorsque l'objet sélectionné est réglé

  • Managed bean + actionListener pour rappeler (ou en retrait) l'objet sélectionné à partir des résultats de recherche

1.2) Définir des variables de composants pour éviter d'exposer les attributs inutiles à l'utilisateur final (développeur)

  • page qui effectue la recherche en fonction des critères (il pourrait être un managedBean + actionLister qui redirige vers la page de recherche

  • Expression représentant la ligne de résultat dataTable (nom d'attribut var) pour définir l'expression de méthode de rappel de actionListener

2) à la page de recherche (chaque type d'entité doit avoir son propre) le bouton de commande (# 4) pour sélectionner la ligne est cr Programmé en fonction de l'interface et des variables du composant. La déclaration est juste <p:commandButton binding=#{dataLookupBean.bind} />.

Enfin, le code qui permet revenir à la mise en page précédente objet sélectionné:

public CommandButton getBind() { 
    try { 
     cb = new CommandButton(); 

     StringBuffer fullCommand = new StringBuffer("#{").append(bean).append(".").append(action).append("(") 
       .append(paramEl).append(")").append("}"); 

     Class<?>[] aParamTypeClazz; 

     aParamTypeClazz = new Class<?>[] { Class.forName(paramType) }; 
     cb.addActionListener(new MethodExpressionActionListener(
       createMethodExpression(fullCommand.toString(), aParamTypeClazz))); 

     if (!BtUtil.isNullOrEmpty(buttonIcon)) 
      cb.setIcon(buttonIcon); 

     if (!BtUtil.isNullOrEmpty(buttonValue)) 
      cb.setValue(buttonValue); 

     return cb; 
    } catch (ClassNotFoundException e) { 
     log.error(e.getMessage(), e); 
     throw new InfraException(e.getMessage()); 
    } 
} 

commandButton de la colonne "Actions" (# 4) sont liés au code ci-dessus.

Maintenant, il est très facile d'ajouter une entrée avec recherche dans une page, juste déclarer quelque chose comme:

<bt:pickerCompetency toolbarMode="true" 
          onSelectBean="reviewFormBean" 
          onSelectAction="doPickIndividualCompetency" /> 

Toute la logique d'ouvrir une page de recherche, de recherche et sélectionnez est fait par sous-jacent code composite. Bien sûr, il y a beaucoup plus de code derrière, mais ce sont toutes les spécificités de l'entreprise. La feuille de route est comme je l'ai décrit ci-dessus. N'hésitez pas à demander quelque chose qui pourrait ne pas être clair.