Comment fonctionne l’atsortingbut ‘binding’ dans JSF? Quand et comment devrait-il être utilisé?

Il existe de nombreux matériaux qui différencient les atsortingbuts de value et binding atsortingbuts de binding dans JSF.

Je m’intéresse à la différence entre les deux approches. Donné:

 public class User { private Ssortingng name; private UICommand link; // Getters and setters omitted. } 
    

Ce qui se passe quand un atsortingbut de value est spécifié est assez simple. Le getter s’exécute pour renvoyer la valeur de la propriété name du bean User . La valeur est imprimée sur la sortie HTML.

Mais je ne pouvais pas comprendre comment fonctionne la binding . Comment le code HTML généré conserve-t-il une liaison avec la propriété link du bean User ?

Vous trouverez ci-dessous la partie pertinente de la sortie générée après l’embellissement manuel et les commentaires (notez que l’id j_id_jsp_1847466274_1 été généré automatiquement et qu’il existe deux widgets d’entrée cachés). J’utilise le JSF RI de Sun, version 1.2.

 
Name

Où la binding stockée ici?

Comment ça marche?

Lorsqu’une vue JSF (fichier Facelets / JSP) est créée / restaurée, une arborescence de composants JSF sera créée. A ce moment, le temps de construction de la vue , tous binding atsortingbuts de binding sont évalués ( ainsi que les atsortingbuts d’ id et les gestionnaires de balises comme JSTL ). Lorsque le composant JSF doit être créé avant d’être ajouté à l’arborescence des composants, JSF vérifie si l’atsortingbut de binding renvoie un composant précréé (c’est-à-dire non null ) et, le cas échéant, l’utilise. Si ce n’est pas préétabli, JSF crée automatiquement le composant “de la manière habituelle” et appelle l’atsortingbut derrière binding atsortingbut de binding avec l’instance de composant créée automatiquement comme argument.

Dans les effets, il lie une référence de l’occurrence de composant dans l’arborescence des composants à une variable de scope. Ces informations ne sont en aucun cas visibles dans la représentation HTML générée du composant lui-même. Ces informations ne sont en aucun cas pertinentes pour la sortie HTML générée. Lorsque le formulaire est soumis et que la vue est restaurée, l’arborescence des composants JSF est simplement reconstruite à partir de zéro et tous binding atsortingbuts de binding seront simplement réévalués comme décrit dans le paragraphe ci-dessus. Une fois l’arborescence des composants recréée, JSF restaurera l’état d’affichage JSF dans l’arborescence des composants.

Les instances de composants ont une scope de requête!

Il est important de savoir et de comprendre que les instances de composants concrets sont bien définies. Ils sont nouvellement créés à chaque demande et leurs propriétés sont remplies avec les valeurs de l’état de la vue JSF lors de la phase d’affichage de la restauration. Ainsi, si vous liez le composant à une propriété d’un bean backing, le bean de sauvegarde ne doit absolument pas être plus étendu que l’étendue de la requête. Voir aussi la spécification JSF 2.0 chapitre 3.1.5:

3.1.5 Liaisons de composants

Les liaisons de composants sont souvent utilisées conjointement avec les JavaBeans instanciés dynamicment via la fonction de création de beans gérés (voir Section 5.8.1 «VariableResolver et le VariableResolver par défaut»). Il est fortement recommandé que les développeurs d’applications placent des beans gérés pointés par des expressions de liaison de composants dans la scope «request». Cela est dû au fait que le placer dans la scope d’une session ou d’une application nécessite une sécurité des threads, car les instances UIComponent dépendent de l’exécution à l’intérieur d’un seul thread. Il existe également des impacts potentiellement négatifs sur la gestion de la mémoire lors de la liaison d’un composant dans une scope «session».

Sinon, les instances des composants sont partagées entre plusieurs requêtes, ce qui peut entraîner des erreurs “d’ ID de composant en double ” et des comportements “étranges” car les validateurs, convertisseurs et écouteurs déclarés dans la vue sont rattachés à l’instance de composant existante. Les symptômes sont clairs: ils sont exécutés plusieurs fois, une fois de plus avec chaque requête dans la même étendue que celle à laquelle le composant est lié.

Et, sous une lourde charge (c’est-à-dire lorsque plusieurs requêtes HTTP (threads) différentes accèdent et manipulent la même instance de composant en même temps), vous risquez tôt ou tard de tomber en panne avec, par exemple, un thread Stuck sur UIComponent.popComponentFromEL à 100% d’utilisation du processeur en utilisant richfaces UIDataAdaptorBase et son HashMap interne , ou même une IndexOutOfBoundsException “étrange” IndexOutOfBoundsException ou ConcurrentModificationException venant directement du code source de l’implémentation JSF alors que JSF est en train d’enregistrer ou de restaurer l’état restoreState() méthodes et similaires).

Utiliser la binding sur une propriété de haricot est une mauvaise pratique

Indépendamment de cela, la liaison de toute une instance de composant à une propriété du bean, même sur un bean de requête, est plutôt rare dans JSF 2.xa et n’est généralement pas la meilleure pratique. Cela indique une odeur de conception. Vous déclarez normalement les composants du côté de la vue et liez leurs atsortingbuts d’exécution comme value , et peut-être d’autres comme styleClass , disabled , rendered , etc., aux propriétés du bean normal. Ensuite, il vous suffit de manipuler exactement la propriété de bean que vous voulez au lieu de saisir tout le composant et d’appeler la méthode setter associée à l’atsortingbut.

Dans les cas où un composant doit être “construit dynamicment” sur la base d’un modèle statique, il est préférable d’utiliser des balises de génération de vues telles que JSTL , si nécessaire dans un fichier de balises , au lieu de createComponent() , new SomeComponent() , getChildren().add() et que non. Voir aussi Comment refactoriser un fragment de l’ancien JSP en un équivalent JSF?

Ou, si un composant doit être “rendu dynamicment” sur la base d’un modèle dynamic, utilisez simplement un composant iterator ( , , etc.). Voir aussi Ajouter dynamicment des composants JSF .

Les composants composites sont une histoire complètement différente. Il est tout à fait légitime de lier des composants dans un composant au composant de sauvegarde (composant identifié par . Voir aussi ao Split java.util.Date sur deux champs h: inputText représentant heure et minute avec f: convertDateTime et Comment implémenter une liste dynamic avec un composant composite JSF 2.0?

N’utiliser que la binding dans la scope locale

Cependant, vous souhaitez parfois connaître l’état d’un composant différent à l’intérieur d’un composant particulier, plus souvent que dans les cas d’utilisation liés à la validation dépendante de l’action / de la valeur. Pour cela, l’atsortingbut de binding peut être utilisé, mais pas en combinaison avec une propriété de bean. Vous pouvez simplement spécifier un nom de variable unique dans l’EL scope local dans l’atsortingbut de binding comme si binding="#{foo}" et le composant est en cours de réponse ailleurs dans la même vue directement comme référence UIComponent disponible par #{foo} . Voici plusieurs questions connexes dans lesquelles une telle solution est utilisée dans la réponse:

  • Validez la saisie uniquement si vous appuyez sur un bouton de commande
  • Comment rendre un composant uniquement si un autre composant n’est pas rendu?
  • JSF 2 index de ligne dataTable sans dataModel
  • Primefaces depend selectOneMenu et required = “true”
  • Valider un groupe de champs si nécessaire lorsque l’un d’entre eux est rempli
  • Comment changer la classe css pour le champ de saisie et l’étiquette lorsque la validation échoue?
  • Obtenir un composant défini par JSF avec Javascript
  • Utiliser une expression EL pour transmettre un ID de composant à un composant composite dans JSF

    (et c’est seulement depuis le mois dernier …)

Voir également:

  • Comment utiliser la liaison de composant dans JSF à droite? (composant à scope de requête dans le bean de session)
  • Étendue de la vue: java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
  • L’atsortingbut de liaison provoque l’ID de composant en double trouvé dans la vue

Chaque composant JSF se convertit en HTML et contrôle complètement le HTML qu’il produit. Il existe de nombreuses astuces qui peuvent être utilisées par JSF, et le choix de ces astuces dépend de l’implémentation JSF que vous utilisez.

  • Assurez-vous que chaque entrée depuis est associée à un nom unique, de sorte que lorsque le formulaire est renvoyé à l’arborescence des composants, il est facile de déterminer où chaque composant peut lire sa forme.
  • Le composant JSF peut générer du javascript renvoyé au sereur, le javascript généré sait également où chaque composant est lié, car il a été généré par le composant.
  • Pour des choses comme hlink, vous pouvez inclure des informations de liaison dans l’URL en tant que parameters de requête ou dans le cadre de l’URL ou en tant que parameters matrx. pour des exemples.

    http:..../somelink?componentId=123 permettrait à jsf de regarder dans l’arborescence des composants pour voir que le lien 123 a été cliqué. ou il pourrait être htp:..../jsf;LinkId=123

Le moyen le plus simple de répondre à cette question consiste à créer une page JSF avec un seul lien, puis à examiner la sortie HTML qu’elle génère. De cette façon, vous saurez exactement comment cela se passe en utilisant la version de JSF que vous utilisez.