在本课中,我们将重点介绍如何使用规则和操作实现组件的行为。

统治

创建组件时,可以编写由表达式和一个或多个操作组成的规则。如果表达式为 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:

让我们确保用户确定他们的选择。例如,如果我们选择“苹果”苹果派开始生产,我们可能希望用户重新确认:

  • 阅读ui_dialog行动
  • 向组件添加一个对话框,显示所选值并要求用户确认其选择。

下载工作流程(预分配)

帮助和资源

  • 对于作业 2,您必须创建一个对<command>ui_dialog选项做出反应的新规则。现有规则的某些逻辑必须移至该新规则。

溶液

下载组件(分配后)

至此,您已经完成了第四节课。在第五课中,我们将探讨仅使用 XML 定义工作流的一些局限性,以及如何在工作流中使用 JavaScript 来解决这些问题。