在本课中,我们将重点介绍如何使用规则和操作实现组件的行为。
创建组件时,可以编写由表达式和一个或多个操作组成的规则。如果表达式为 true,则将执行这些操作。规则由三个元素组成:
规则也将始终分配给一个州:
<onenter>
:这是进入步骤时的第一个状态。用户界面在此状态下不可用,因此,您不能使用与 UI 相关的操作。但是,如果要初始化参数以将其用于 UI 映射,则这是执行此操作的正确状态。<onresume>
:之后 <onenter>
的第二个状态。在此状态下,UI 可用,您可以使用 UI 更新操作修改加载的布局。<onpause>
和 <onleave>
:每当使用step_transition
or finish_workflow
操作离开当前步骤或整个组件时,都会发生这些状态。由于转换是不可中断的,因此您不能在此处使用使用这些操作的规则。在状态下 onpause
,步骤的资源仍然存在,但 onleave
不存在。<onevent>
:这可能是最重要的状态。每次处理事件时,都会检查在此状态下定义的规则。与与用户交互相关的所有规则都在此状态下定义。状态中的规则是按任意顺序计算的,因此规则的表达式不应依赖于在它之前检查的另一条规则。
另一方面, 规则中的操作将按照您写下的顺序执行。
评估/执行顺序:
表达式的一般结构由操作数 (例如上下文变量)和 运算符 (例如“=”或“>”)组成 ,就像在任何编程语言中一样。
支持的运算符:+、-、&&、||、!、/、==、>、>=、<、<=、%、*、!=
让我们看一下“分页文本”组件中的另一个简单示例,该示例在多个页面上显示任意长度的文本:
<onevent> <rule id=“next_page”> <expression><![CDATA[ #{event:command} == 'NEXT_PAGE' && #{page} < #{numberofpages} ]]></expression> <actions> <action ref=“next”/> <action ref=“settext”/> </actions> </rule> </onevent>
提示和技巧:
-> 除非空格被标记为带有单引号的字符串,否则将从表达式中删除空格,因此您可以自由使用新行来使表达式具有可读性。
->当按下按钮 name="NEXT_PAGE"
时,此表达式变为 true,并且当前页面不是最后一页。
-> 您可能已经注意到 <![CDATA[ ... ]]>
表达式周围的标签。在这种情况下,标记是必需的。它是一个 XML 关键字,用于通知解析器后面的内容没有标记。如果没有标记 <![CDATA[ ... ]]>
,此表达式将使组件的 XML 失效,因为它包含 XML 保留字符 &
和 . <
-> 向所有表达式添加标签 <![CDATA[ ... ]]>
。这样,您就不必考虑是否使用 XML 保留字符。
当规则处于 <onevent>
步骤状态时,您可以对事件做出反应,并在表达式中使用事件的属性。事件的结构如下:
{ “command”: “...“, ”device“: { ”modality“: ”...“, ”name“: ”...“, ”source“: ”...“, ”descriptor“: ”...“ }, ”有效载荷“: { ”...": "...“, ”error“: ”...“ } }
您只需要以下字段的子集:
1. command: 此事件的命令,例如“NEXT”。例如,该命令可能对应于组件的布局或工作流描述中的 ID。示例:#{event:command} == 'CANCEL'
2. device.modality: 事件的来源。可以使用简短的表示法访问此字段。
表达式 #{event(SPEECH):command=='NEXT' 等效于表达 式 #{event:device.modality} == 'SPEECH' && #{event:command} == 'NEXT'。模式取决于事件发射器。示例,#{event:device.modality} == 'MENU_SELECTION'
3. 有效负载: 有效负载的结构/字段取决于触发事件的操作/处理程序。示例,#{event:payload.amount}
4. payload.error: 包含错误消息(如果有)。示例 #{event:payload.error}
您可以限制事件源,以确保仅当事件由特定输入模式引起时才会触发规则。例如,您可以有一个语音命令“NEXT”,工作人员可以使用该命令来确认他们已完成特定任务或产品的工作。他们可能还使用通过命令“NEXT”触发事件的设备。按下硬件按钮时,它会在屏幕上的可用选项之间旋转。您不希望在使用硬件按钮时激活规则,因此您可以指定模式: #{event(SPEECH):command} == 'NEXT'
。
常规事件源(模态):语音、手势、键盘、条形码、HW_KEYS、CAMERA_PICTURE、MENU_SELECTION、MEDIA_INPUT
让我们来看看一些相对频繁出现的规则结构:
我们的第一个示例处理了一个典型的用例:在进入或离开组件时自动执行操作。
提示和技巧: 有些规则需要无条件执行。为此,您可以将表达式设置为 <expression>1</expression>
。
<onresume> <rule id=“init”> <expression>1</expression> <actions> <action ref=“reset_counter”/> </actions> </rule> </onresume>
状态内的规则按任意顺序进行评估。在某些情况下,您需要在同一步骤中按顺序执行规则。为此,您可以使用计时器按顺序触发规则。计时器操作使用用户定义的命令手动触发事件。
作为第一条规则的最后一个操作,您将添加计时器操作。然后,可以将用户定义的命令添加到第二个规则的表达式中。
<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>
作业 1:
在我们的“选择”组件中,我们没有使用<![CDATA[ ... ]]>
标签来使组件对初始学习者尽可能简单。作为最佳实践,我们建议在所有表达式中使用该标记,以消除潜在的错误源。
<![CDATA[ ... ]]>
将标记添加到我们的现有规则中。作业 2:
让我们确保用户确定他们的选择。例如,如果我们选择“苹果”苹果派开始生产,我们可能希望用户重新确认:
<command>
ui_dialog
选项做出反应的新规则。现有规则的某些逻辑必须移至该新规则。至此,您已经完成了第四节课。在第五课中,我们将探讨仅使用 XML 定义工作流的一些局限性,以及如何在工作流中使用 JavaScript 来解决这些问题。