Événements et opérations
Les gestionnaires d'événements permettent à un schéma de réagir à ce qui se passe dans un formulaire, comme le chargement d'un enregistrement ou la modification d'un champ. Un gestionnaire ne modifie jamais directement le formulaire. Il décrit ce qui doit se passer sous forme d'une liste d'opérations, et l'application host les applique. Cette page explique comment les gestionnaires sont enregistrés, ce qu'ils peuvent lire et comment leurs opérations sont appliquées.
Pour savoir quels événements les renderers officiels déclenchent, voir Déclenchement des événements dans les bindings officiels.
Enregistrer des gestionnaires
Le code de form.events.code s'exécute une fois, à la création du moteur. Chaque appel à ON
enregistre un gestionnaire, et chaque appel à OFF en supprime un :
Code
- Les bindings officiels identifient le champ par son
data_name: les gestionnaires des événements de champ déclenchés par les bindings doivent donc eux aussi s'enregistrer avec ledata_name. Le core compare la chaîne d'enregistrement à l'identique et ne convertit pas entrekeyetdata_name. - Omettez le champ pour exécuter le gestionnaire pour tous les champs.
- Un type d'événement inconnu affiche un avertissement, et le gestionnaire n'est pas enregistré.
- Enregistrez chaque gestionnaire au niveau supérieur de
form.events.code.ONetOFFappelés à l'intérieur d'un gestionnaire n'ont aucun effet.
Quand les gestionnaires s'exécutent
Un gestionnaire ne s'exécute que lorsque son événement est déclenché, soit par un binding, soit par
votre application avec engine.trigger(eventType, fieldDataName, metadata). Créer le moteur ou
exécuter eval() ne déclenche aucun événement.
Pour un même déclenchement, les gestionnaires enregistrés pour ce champ s'exécutent d'abord, dans
l'ordre de leur enregistrement. Les gestionnaires enregistrés pour tous les champs s'exécutent
ensuite. Si un gestionnaire lève une erreur, le moteur affiche [form0] Expression evaluation failed
dans la console et les autres gestionnaires s'exécutent quand même.
Ce qu'un gestionnaire peut lire
Un gestionnaire lit les valeurs des champs avec $data_name, comme un calcul. Il voit les valeurs du
moment où l'événement a été déclenché. Pour un événement change venant d'un renderer officiel,
c'est après la passe d'évaluation qui a suivi la modification : les champs calculés sont donc déjà à
jour.
Les champs qu'un gestionnaire peut lire dépendent de l'événement :
- Les événements d'enregistrement, comme
load-recordetedit-record, ne peuvent lire que les champs du formulaire principal. - Les événements de champ, comme
change, suivent les mêmes règles qu'un calcul défini sur le champ qui les a déclenchés. Voir Portées parent et enfant.
Chaque gestionnaire reçoit aussi un objet event avec type, fieldKey (le data_name du champ)
et timestamp, ainsi que les métadonnées éventuellement passées à trigger(). Les renderers
officiels ajoutent la nouvelle value et la définition field aux événements change.
Les gestionnaires peuvent utiliser les builtins d'expression partagés, comme IF et CHOICEVALUE,
en plus des builtins d'événement. Les builtins réservés aux calculs, comme SETRESULT, ne sont pas
disponibles.
SETVALUE ne met pas à jour ce que lit le gestionnaire
SETVALUE ne fait qu'enregistrer une opération. Pour le reste du gestionnaire, $data_name
renvoie toujours la valeur du moment où l'événement a été déclenché. La nouvelle valeur est
visible une fois que le host a appliqué l'opération.
Opérations
SETVALUE et ALERT ajoutent chacun une opération à la liste renvoyée par engine.trigger() :
Code
Les opérations de tous les gestionnaires d'un même déclenchement sont renvoyées ensemble, dans l'ordre d'exécution des gestionnaires.
Les opérations sont vérifiées avant d'être renvoyées
Avant que trigger() ne renvoie son résultat, le moteur vérifie chaque SETVALUE par rapport à la
portée du gestionnaire. Un SETVALUE qui cible un champ que le gestionnaire ne peut pas lire, ou un
champ absent du schéma, est retiré de la liste, et le moteur signale un avertissement. Chaque
SETVALUE renvoyé par trigger() cible un champ que le gestionnaire a le droit de modifier.
Comment les bindings officiels appliquent les opérations
Par défaut, les renderers officiels :
- affichent chaque
ALERTdans leur propre boîte de dialogue ; et - écrivent la valeur de chaque
SETVALUEdans le formulaire et exécutent une nouvelle passe d'évaluation.
Les valeurs SETVALUE des champs à choix doivent être portables
Le binding React convertit une valeur de choix primitive comme "it" dans la forme de valeur
d'exécution du champ, mais React Native n'effectue pas encore cette conversion. Tant que les
bindings ne partagent pas un contrat de normalisation unique, utilisez les formes canoniques
d'exécution quand SETVALUE cible un champ à choix. Voir la référence de
SETVALUE pour des exemples.
Le FormRenderer de React Native permet à une application de traiter les opérations autres que les
alertes en passant engineOptions.onOperations. Il continue d'afficher les opérations ALERT dans
sa propre boîte de dialogue et transmet les autres opérations à votre callback. Le FormRenderer de
React traite actuellement les opérations en interne et n'expose pas de callback personnalisé.
Code
Appelez applyDefault avec les opérations que React Native doit traiter comme d'habitude.
Appliquer les opérations sans renderer
Si vous utilisez form0-core directement, appliquez vous-même la liste renvoyée. Pour SETVALUE,
écrivez la valeur et exécutez eval(), comme décrit dans
Cycle d'évaluation. Les champs à choix nécessitent leur forme de
valeur d'exécution, et non une simple valeur de choix.
Pas de chaîne d'événements de modification
Appliquer un SETVALUE exécute une nouvelle passe d'évaluation, mais ne déclenche pas change pour
le champ défini. Un gestionnaire change pour age qui définit adult_note n'exécute pas les
gestionnaires change de adult_note.
Si la définition d'un champ doit aussi déclencher la logique d'un autre, placez les deux dans le
même gestionnaire, ou utilisez un CalculatedField quand la valeur peut être dérivée d'autres
champs.