Dans cette leçon, nous nous concentrerons sur la manière de mettre en œuvre le comportement d'un composant à l'aide de règles et d'actions.
Nous avons déjà appris que lorsque vous créez vos propres composants, vous écrivez des règles composées d'une expression et d'une ou plusieurs actions. La ou les actions seront exécutées si l'expression est vraie.
Règle
Une règle se compose de trois éléments :
- ID : identifiant de la règle qui doit être unique à l'intérieur d'un champ d'application
- Expression : Condition qui déclenche cette règle
- Actions : Références ou définitions des actions qui sont exécutées lorsque cette règle est déclenchée.
Une règle sera également toujours assignée à un état:
États
<onenter> :
Il s'agit du premier état lorsqu'une étape est franchie. L'interface utilisateur n'est pas disponible dans cet état et, par conséquent, vous ne pouvez pas utiliser les actions liées à l'interface utilisateur. Toutefois, si vous souhaitez initialiser des paramètres afin de les utiliser pour le mappage de l'interface utilisateur, il s'agit de l'état correct pour le faire.<onresume> :
Le deuxième état après <onenter>. Dans cet état, l'interface utilisateur est disponible et vous pouvez modifier la présentation 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 en utilisant les actions step_transition
ou finish_workflow
. Les transitions n'étant pas interruptibles, il n'est pas possible d'utiliser ici des règles faisant appel à ces actions. Dans l'état onpause
, les ressources de l'étape existent toujours ; dans l'état onleave,
elles n'existent pas.<onevent> :
Il s'agit probablement de l'état le plus important. Les règles définies dans cet état seront vérifiées chaque fois qu'un événement sera traité. Toutes les règles liées aux interactions avec l'utilisateur sont définies dans cet état.
Les règles 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.
En revanche, les actions d'une règle sont exécutées dans l'ordre où vous les écrivez.
Ordre d'évaluation/exécution:
- Les règles sont vérifiées dans un ordre arbitraire.
- Les actions d'une règle sont exécutées dans un ordre séquentiel.
Expressions
La structure générale d'une expression est composée d'opérandes (par exemple, des variables contextuelles) et d'opérateurs (par exemple, '=' ou '>') comme dans tout langage de programmation.
Opérateurs pris en charge: +, -, &&, ||, !, /, ==, >, >=, <, <=, %, *, !=
Examinons un autre exemple simple du composant "Texte paginé" qui affiche un texte d'une 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 de caractères avec des guillemets simples, de sorte que vous pouvez librement utiliser de nouvelles lignes pour rendre votre expression lisible.
- Cette expression devient vraie lorsque le bouton
name="NEXT_PAGE"
est enfoncé et que la page actuelle n'est pas la dernière. - Vous avez peut-être remarqué la balise
< ![CDATA[ ... ]]>
qui entoure l'expression. Cette balise est nécessaire dans ce cas. Il s'agit d'un mot-clé XML qui informe l'analyseur que ce qui suit n'est pas balisé. Sans la balise < ![CDATA[ ... ]]>
, cette expression invaliderait le XML de notre composant parce qu'elle contient les caractères réservés au XML &
et <.
- Ajoutez une balise
< ![CDATA[ ... ]]>
à toutes vos expressions. De cette manière, vous ne devez pas vous demander si vous utilisez des caractères réservés par XML.
Evénements
Lorsque votre règle se trouve dans l'état <onevent>
d'une é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 :
{
"command": "...",
"device":
{
"modality": "...",
"name": "...",
"source": "...",
"descriptor": "..."
},
"payload":
{
"...": "...",
"error": "..."
}
}
Vous n'aurez besoin que d'un sous-ensemble de ces champs :
1. commande : La commande de cet événement, par exemple "NEXT". La commande peut, par exemple, correspondre à un identifiant dans la description de la présentation ou du flux de travail de votre composant. Exemple : #{événement:commande} == 'ANNULER'
2. dispositif.modalité : La source de l'événement. Ce champ est accessible à l'aide d'une notation courte.
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. charge utile : La structure/les champs de la charge utile 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 pourriez avoir une commande vocale "SUIVANT" 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 dispositif qui déclenche un événement avec la commande "SUIVANT". Lorsqu'on appuie sur un bouton matériel, celui-ci fait défiler les options disponibles à l'écran. Vous ne souhaitez pas activer la règle lorsque les boutons matériels sont utilisés, c'est pourquoi vous spécifiez la modalité : #{événement(SPEECH):commande} == 'SUIVANT'.
Sources d'événements généraux (modalités): PAROLE, GESTE, CLAVIER, CODE-BARRES, HW_KEYS, CAMERA_PICTURE, MENU_SELECTION, MEDIA_INPUT
Exemples
Passons en revue quelques constructions de règles qui apparaissent relativement souvent :
Initialisation et démontage
Notre premier exemple aborde un cas d'utilisation typique : L'exécution automatique d'actions à l'entrée ou à la sortie d'un composant.
Conseils et astuces : Certaines règles doivent être exécutées sans condition. Dans ce cas, vous pouvez donner à l'expression la valeur <expression>1</expression>
.
<onresume>
<rule id="init">
<expression>1</expression>
<actions>
<action ref="reset_counter"/>
</actions>
</rule>
</onresume>
Exécution séquentielle des règles
Les règles d'un état sont évaluées dans un ordre arbitraire. Dans certaines situations, il est nécessaire que les règles soient exécutées de manière séquentielle au cours d'une même étape. Pour ce faire, vous pouvez utiliser une minuterie pour déclencher les règles dans un ordre séquentiel. L'action de la minuterie déclenche manuellement un événement à l'aide d'une commande définie par l'utilisateur.
Comme dernière action de la première règle, vous ajouterez une action de temporisation. 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>
Affectation
Passons à l'action :
Affectation 1 :
Dans notre composant "Choix", nous n'avons pas utilisé la balise < ![CDATA[ ... ]]>
pour que le composant reste aussi simple que possible pour l'apprenant initial. En tant que meilleure pratique, nous recommandons d'utiliser la balise dans toutes vos expressions afin d'éliminer une source d'erreur potentielle.
- Ajoutez la balise
< ![CDATA[ ... ]]>
à notre règle existante.
Affectation 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 vouloir que l'utilisateur le réaffirme :
- Lire la suite de l'action ui_dialog
- Ajoutez une boîte de dialogue au composant qui affiche la valeur sélectionnée et demande à l'utilisateur de confirmer sa sélection.
Télécharger le flux de travail (pré-affectation)
Aide et ressources
- Pour l'exercice 2, vous devrez créer une nouvelle règle qui réagit à la
<commande>
des options ui_dialog
. Une partie de la logique de la règle existante devra être déplacée vers cette nouvelle règle.
Solution
Composant de téléchargement (après l'affectation)
Vous avez ainsi terminé la quatrième leçon. Dans la cinquième leçon, nous examinerons certaines limites de la définition des flux de travail avec seulement XML et la façon dont vous pouvez utiliser JavaScript dans les flux de travail pour résoudre ces problèmes.