2009-12-21 7 views
8

Avant de continuer, voir ce questionComment récupérer une valeur de composant JSF en utilisant EL?

Il est sous forme JSF est présenté à nouveau comme suit:

<f:view> 
    <h:form> 
     <div> 
      <label>Id</label> 
      <input type="text" name="accountId"/> 
     </div> 
     <div> 
      <label>Amount</label> 
      <input type="text" name="amount"/> 
     </div> 
     <h:commandButton value="Withdraw" action="#{accountService.withdraw(param.accountId, param.amount)}"/> 
    </h:form> 
</f:view> 

Notez que je l'ai utilisé <input type="text" name="amount"> au lieu de <h:inputText id="amount">. Pour récupérer sa valeur à l'aide du résolveur EL Seam, j'utilise param.amount.

Il se trouve que si j'utilise <input type="text" et que quelque chose ne va pas du côté serveur, j'ai besoin d'afficher à nouveau la page. Donc, sa valeur soumise n'est pas récupérée car il s'agit d'un code html simple. À cause de cela, j'ai besoin d'utiliser un composant JSF <h:inputText à la place.

Donc la question est: Comment puis-je récupérer une valeur de composant JSF <h:inputTexten utilisant le langage d'expression?

+0

Pour commencer, votre question était assez confuse. On dirait que l'histoire de Seam est complètement hors de propos ici. Dans l'avenir, s'il vous plaît poster le code JSF que vous avez ** réellement ** et dites exactement ce que vous voulez faire avec ** votre ** code. – BalusC

+0

Cela n'a pas non plus de sens. En JSP/Servlet simple, vous auriez pu utiliser '' pour cela. – BalusC

+0

Je vous recommande fortement de vous familiariser avec un livre/tutoriel JSF décent pour comprendre comment fonctionne JSF "sous le capot". Apprendre aussi "simple vanilla" JSP/Servlet aiderait beaucoup à le comprendre. Vous faites des suppositions et essayez de briser l'idéologie de JSF en prenant tout son travail entre vos mains. Désolé si j'ai l'air dur, mais c'est la vérité. – BalusC

Répondre

18

le client JSF identifiants sont précédés par l'ID de cliend des composants parent UINamingContainer (par exemple h:form, h:dataTable, f:subview). Si vous vérifiez la source HTML générée dans votre navigateur Web (clic droit, afficher la source), vous devriez les voir. Les éléments id et name des éléments d'entrée générés sont ajoutés au id du formulaire parent. Vous devez utiliser le même nom que la clé dans la carte des paramètres. Comme le caractère séparateur, le colon :, est un caractère "illégal" dans EL, vous devez utiliser la notation accolade param['foo:bar'] pour les récupérer.

<f:view> 
    <h:form id="account"> 
     <div> 
      <label>Id</label> 
      <h:inputText id="id" /> 
     </div> 
     <div> 
      <label>Amount</label> 
      <h:inputText id="amount" /> 
     </div> 
     <h:commandButton value="Withdraw" 
      action="#{accountService.withdraw(param['account:id'], param['account:amount'])}"/> 
    </h:form> 
</f:view> 

Sans paramètres de la méthode Seam-EL-like (apparemment vous ne voulez pas/ont), vous pouvez également y accéder à la carte des paramètres de demande en utilisant l'ID client est comme clés:

public void withDraw() { 
    Map<String, String> map = FacesContext.getCurrentInstance().getRequestParameterMap(); 
    String id = map.get("account:id"); 
    String amount = map.get("account:amount"); 
    // ... 
} 

Inutile de dire que c'est méchant. Faites-le simplement de la manière JSF normale, liez les valeurs avec les propriétés du bean.

Edit: selon la dernière question que vous avez modifié:

La question est donc: comment puis-je récupérer une valeur de composante <h:inputText JSF en utilisant un langage d'expression?

Ceci a déjà été répondu auparavant. Utilisez le nom généré par JSF comme nom de paramètre. Ceci est généralement dans le modèle de formId:inputIdformId est le id du composant parent UIForm et le inputId est le id du composant UIInput. Vérifiez la sortie HTML générée pour le nom exact du champ <input type="text"> généré. Pour obtenir la valeur du paramètre, utilisez la notation d'accolade ['name'], car vous ne pouvez pas utiliser les deux-points : dans EL comme dans ${param.formId:inputId}.

Ainsi:

#{param['formId:inputId']} 
+0

Hm, c'était ta propre réponse et ça devait marcher? Eh bien, je ne peux que suggérer de vérifier la sortie HTML générée pour voir si les noms sont corrects et/ou s'ils sont disponibles dans la carte des paramètres de la requête. – BalusC

+0

Donc, vous dites que vous avez en fait un 'h: inputText' dans votre page JSF et non' '? De cette façon, vous devez lui donner (et la forme parent) un 'id' et obtenir le param avec l'ID client généré comme clé. Je vais éditer ma réponse bientôt. – BalusC

+0

Ils figurent dans la carte des paramètres de la requête. Avez-vous par exemple débuggé son contenu? 'System.out.println (requestParameterMap);' de sorte que vous pouvez les voir et les modèles? – BalusC

1

Les noms de paramètres/ids pour inputText sont encapsulées par le moteur de rendu de contrôle et sont, en fin de compte, un détail de mise en œuvre. En pratique, ils utilisent le clientId. Il ne devrait pas être nécessaire de les lire directement à partir de la carte des paramètres; Utilisez la valeur de liaison pour les pousser dans le modèle et les lire à partir de là.

Vous pouvez lire les valeurs directement à partir du composant en utilisant EL en liant le composant à un bean géré. Par souci de simplicité, voici une limite à la portée de la demande:

<!-- bind a UIComponent to the request map as "foo" --> 
<h:inputText binding="#{requestScope.foo}" /> 
<!-- read value from a UIComponent that implements ValueHolder --> 
#{requestScope.foo.value} 

Mais, en général, il n'y a aucun avantage à ce cours:

<!-- bind a value to the request map as "foo" --> 
<h:inputText value="#{requestScope.foo}" /> 
<!-- read value from the request scope --> 
#{requestScope.foo} 

Pour éviter de polluer la carte de demande (ce qui pourrait entraîner des collisions entre views), utilisez un bean géré dans l'espace de nom/encapsulez vos valeurs plutôt que d'utiliser directement l'étendue de la requête.

+0

Bonne insistance, MCDowell. (+1) –

0

Bien que je puisse récupérer la valeur des composants JSF par son identifiant client, il y a quelques inconvénients comme suit:

  1. Selon la réponse de McDowell, l'identifiant client est un détail d'implémentation
  2. L'identifiant client peut différer l'identificateur de composant lorsqu'il existe plusieurs conteneurs d'attribution de noms dans la hiérarchie de contrôle. (JSF dans le livre d'action)

Donc, si vous ne voulez pas compter sur identifiant client, vous pouvez mettre en œuvre votre propre ElResolver comme suit:

public class ComponentIdResolver extends ELResolver { 

    public Object getValue(ELContext context, Object base, Object property) { 
     if (base instanceof UIComponent && property instanceof String) { 
      UIComponent r = ((UIComponent) base).findComponent((String) property); 

      if (r != null) { 
       context.setPropertyResolved(true); 

       return r; 
      } 
     } 

     return null; 
    } 

} 

je peux maintenant utiliser quelque chose comme (Notez retirer méthode)

<h:inputText id="accountId" /> 
<h:inputText id="amount" /> 
<h:commandButton value="Withdraw" action="#{accountService.withdraw(view.accountId.value, view.amount.value)}"/> 

vue est un objet JSF implicite (similaire à FacesContext.getCurrentInstance(). getViewRoot())

Ensuite reg Ister votre ELResolver comme indiqué ci-dessous (faces-config.xml)

<application> 
    <el-resolver>br.com.view.resolver.ComponentIdResolver</el-resolver> 
</application> 

Si vous voulez en savoir un bon aperçu sur ElResolver voir Extending the Java EE Unified Expression Language with a Custom ELResolver

salutations

Questions connexes