Dans cette leçon, nous allons nous concentrer sur la façon d’implémenter le comportement d’un composant avec des règles et des actions.
Lors de la création de composants, il est possible d’écrire des règles composées d’une expression et d’une ou plusieurs actions. Les actions seront exécutées si l’expression est vraie. Une règle se compose de trois éléments :
De plus, une règle sera toujours affectée à un état :
<onenter>
: Il s’agit du premier état lorsqu’une étape est saisie. L’interface utilisateur n’est pas disponible dans cet état, par conséquent, vous ne pouvez pas utiliser d’actions liées à l’interface utilisateur. Toutefois, si vous souhaitez initialiser des paramètres pour les utiliser pour le mappage de l’interface utilisateur, il s’agit de l’état approprié pour le faire.<onresume>
: Le deuxième état après <onenter>
. Dans cet état, l’interface utilisateur est disponible et vous pouvez modifier la disposition chargée à l’aide des actions de mise à jour de l’interface utilisateur.<onpause>
et <onleave>
: ces états se produisent chaque fois que vous quittez l’étape en cours ou l’ensemble du composant à l’aide des step_transition
actions ou . finish_workflow
Étant donné que les transitions ne sont pas interruptibles, vous ne pouvez pas utiliser ici des règles qui utilisent ces actions. Dans l’État onpause
, les ressources de l’étape existent toujours, mais onleave
elles n’existent pas.<onevent>
: C’est probablement l’état le plus important. Les règles définies dans cet état seront vérifiées chaque fois qu’un événement est traité. Toutes les règles liées aux interactions avec l’utilisateur sont définies dans cet état.Les règles au sein d’un état sont évaluées dans un ordre arbitraire, de sorte que l’expression d’une règle ne doit pas dépendre d’une autre règle vérifiée avant elle.
D’autre part, les actions au sein d’une règle sont exécutées dans l’ordre dans lequel vous les écrivez.
Ordre d’évaluation/exécution :
La structure générale d’une expression est composée d’opérandes (par exemple, des variables de contexte) et d’opérateurs (par exemple, '=' ou '>') comme dans n’importe quel langage de programmation.
Opérateurs pris en charge : +, -, &&, ||, !, /, ==, >, >=, <, <=, %, *, !=
Jetons un coup d’œil à un autre exemple simple du composant « Texte paginé » qui montre un texte de longueur arbitraire sur plusieurs pages :
<onevent> <rule id="next_page"> <expression>< ![ CDATA[ #{event :command} == 'NEXT_PAGE' &&& #{page} < #{numberofpages} ]]></expression> <actions> <action ref="next"/> <action ref="settext"/> </actions> </rule> </onevent>
Trucs et astuces :
-> Les espaces blancs seront supprimés de l’expression à moins qu’ils ne soient marqués comme des chaînes avec des guillemets simples, vous pouvez donc utiliser librement de nouvelles lignes pour rendre votre expression lisible.
->Cette expression devient vraie lorsque le bouton name="NEXT_PAGE"
est enfoncé et que la page en cours n’est pas la dernière page.
-> Vous avez peut-être remarqué la <![CDATA[ ... ]]>
balise entourant l’expression. La balise est requise dans ce cas. Il s’agit d’un mot-clé XML qui informe l’analyseur que ce qui suit n’est pas un balisage. Sans la <![CDATA[ ... ]]>
balise, cette expression invaliderait le code XML de notre composant, car elle contient les caractères &
réservés au format XML et . <
-> Ajoutez une <![CDATA[ ... ]]>
balise à toutes vos expressions. De cette façon, vous n’avez pas à vous demander si vous utilisez des caractères réservés au XML.
Lorsque votre règle est à l’état <onevent>
d’étape, vous pouvez réagir aux événements et utiliser les propriétés de l’événement dans votre expression. La structure d’un événement est la suivante :
{ "commande » : « ... « , "device » : { "modality » : « ... « , "nom » : « ... « , "source » : « ... « , "descripteur » : « ... « }, "charge utile » : { »... ": "... « , "erreur » : « ... " } }
Vous n’aurez besoin que d’un sous-ensemble de ces champs :
1. command : La commande de cet événement, par exemple, « NEXT ». La commande peut, par exemple, correspondre à un ID dans la description de la mise en page ou du workflow de votre composant. Exemple : #{event :command} == 'ANNULER'
2. device.modality : source de l’événement. Ce champ est accessible à l’aide d’une courte notation.
L’expression #{event(SPEECH) :command=='NEXT' est équivalente à l’expression #{event :device.modality} == 'SPEECH' && #{event :command} == 'NEXT'. La modalité dépend de l’émetteur de l’événement. Exemple, #{event :device.modality} == 'MENU_SELECTION'
3. payload : La structure/les champs de la payload dépendent de l’action/du gestionnaire qui déclenche l’événement. Exemple, #{event :payload.amount}
4. payload.error : Contient un message d’erreur s’il y en a un. Exemple, #{event :payload.error}
Vous pouvez restreindre les sources d’événements pour vous assurer qu’une règle ne se déclenche que lorsque l’événement est causé par une modalité d’entrée spécifique. Par exemple, vous pouvez avoir une commande vocale « NEXT » que les travailleurs peuvent utiliser pour confirmer qu’ils ont terminé leur travail sur une tâche ou un produit particulier. Ils peuvent également utiliser un appareil qui déclenche un événement avec la commande « NEXT ». Lorsque vous appuyez sur un bouton matériel, il passe d’une option à l’autre à l’écran. Vous ne souhaitez pas activer la règle lorsque les boutons matériels sont utilisés, vous devez donc spécifier la modalité : #{event(SPEECH):command} == 'NEXT'
.
Sources générales d’événements (modalités) : PAROLE, GESTE, CLAVIER, CODE-BARRES, HW_KEYS, CAMERA_PICTURE, MENU_SELECTION, MEDIA_INPUT
Passons en revue quelques constructions de règles qui apparaissent relativement souvent :
Notre premier exemple s’attaque à un cas d’utilisation typique : l’exécution automatique d’actions lors de l’entrée ou de la sortie d’un composant.
Trucs et astuces : Certaines règles doivent être exécutées sans condition. Pour ce faire, vous pouvez définir l’expression sur <expression>1</expression>
.
<onresume> <rule id="init"> <expression>1</expression>< actions> <action ref="reset_counter"/> </actions>< /rule> </onresume>
Les règles au sein d’un État sont évaluées dans un ordre arbitraire. Dans certaines situations, vous avez besoin que les règles soient exécutées de manière séquentielle au cours de la même étape. Pour cela, vous pouvez utiliser un minuteur pour déclencher les règles dans l’ordre séquentiel. L’action du minuteur déclenche manuellement un événement à l’aide d’une commande définie par l’utilisateur.
En tant que dernière action de la première règle, vous allez ajouter une action de minuterie. La commande définie par l’utilisateur peut ensuite être ajoutée à l’expression de la deuxième règle.
<onevent> <rule id="first_rule"> <expression>< ![ CDATA[ #{event :command}=='VALID' ]]></expression> <actions> <action ref="do_something"/> <setvar id="increment_counter"> <context_of>workflow</context_of> <context_update> <param name="counter » type="long">#{counter} + 1</param> </context_update> </setvar> <timer id="check_counter_trigger » command="CHECK_COUNTER » delay="0"/> </actions> </rule> <rule id="second_rule"> <expression>< ![ CDATA[ #{event :command}=='CHECK_COUNTER' &&& #{counter} >= #{max_iterations} ]]></expression> <actions><finish_workflow id="exit"/> </actions> </rule> </onevent>
Devoir 1 :
Dans notre composant « Choix », nous n’avons pas utilisé la <![CDATA[ ... ]]>
balise pour garder le composant aussi simple que possible pour l’apprenant initial. Il est recommandé d’utiliser la balise dans toutes vos expressions afin d’éliminer une source d’erreur potentielle.
<![CDATA[ ... ]]>
balise à notre règle existante.Devoir 2 :
Assurons-nous que l’utilisateur est certain de son choix. Si, par exemple, dès que nous choisissons « Apple », des tartes aux pommes commencent à être produites, nous pourrions souhaiter que l’utilisateur réaffirme :
Workflow de téléchargement (pré-affectation)
<command>
ui_dialog
des options. Une partie de la logique de la règle existante devra être transférée à cette nouvelle règle.Télécharger le composant (post-affectation)
Sur ce, vous avez terminé la quatrième leçon. Dans la cinquième leçon, nous examinerons certaines limites de la définition de flux de travail avec uniquement XML et comment vous pouvez utiliser JavaScript dans les flux de travail pour résoudre ces problèmes.