このレッスンでは、ルールとアクションを使用してコンポーネントの動作を実装する方法に焦点を当てます。

支配

コンポーネントを作成するときは、式と 1 つ以上のアクションで構成されるルールを記述できます。式が true の場合、アクションが実行されます。ルールは、次の 3 つの要素で構成されます。

  • 身分証明書:スコープ内で一意である必要があるルール識別子
  • 表現:このルールをトリガーする条件
  • アクション:このルールがトリガーされたときに実行されるアクションの参照または定義

また、ルールは常に状態に割り当てられます。

列国

  • <onenter>:ステップに入ったときの最初の状態です。この状態ではユーザー インターフェイスは使用できないため、UI 関連のアクションを使用できません。ただし、UI マッピングに使用するようにパラメーターを初期化する場合は、これが正しい状態です。
  • <onresume>: の後の 2 番目の状態 <onenter>。この状態では、UI が使用可能であり、UI 更新アクションを使用して読み込まれたレイアウトを変更できます。
  • <onpause> および <onleave>: これらの状態は、または finish_workflow アクションを使用して step_transition 現在のステップまたはコンポーネント全体を終了するたびに発生します。遷移は中断できないため、これらのアクションを使用するルールをここで使用することはできません。この状態では、ステップのリソースはまだ存在しますが、onleave  存在しません。 onpause 
  • <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" が押されたときに真になり、現在のページが最後のページではなくなります。

 

->式を囲むタグに気付いた <![CDATA[ ... ]]> かもしれません。この場合、タグは必須です。これは、その後に続くものがマークアップではないことをパーサーに通知する XML キーワードです。タグがないと、この式には XML 予約文字  &と . < <![CDATA[ ... ]]> 

 

-> すべての式にタグを追加します <![CDATA[ ... ]]> 。これにより、XML 予約文字を使用しているかどうかを考える必要がなくなります。

イベント

ルールがステップの状態にある <onevent> ときは、イベントに反応し、式でイベントのプロパティを使用できます。イベントの構造は次のとおりです。

   {
          "コマンド": "...",
          "device":
          {
             "modality": "...",
             "名前": "...",
             "ソース": "...",
             "記述子": "..."
          },
          "ペイロード":
          {
             "...": "...",
             "エラー": "..."  
          }
    }

必要なのは、次のフィールドのサブセットのみです。

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. payload: ペイロードの構造/フィールドは、イベントをトリガーするアクション/ハンドラーに依存します。例: #{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>    

ルールの逐次実行

状態内のルールは、任意の順序で評価されます。状況によっては、同じステップ内でルールを順番に実行する必要があります。このために、タイマーを使用してルールを順番にトリガーできます。タイマー アクションは、ユーザー定義のコマンドを使用して手動でイベントをトリガーします。

最初のルールの最後のアクションとして、タイマー アクションを追加します。その後、ユーザー定義コマンドを 2 番目のルールの式に追加できます。

<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:

ユーザーが自分の選択に確信を持っていることを確認しましょう。たとえば、「Apple」アップルパイの生産を開始するとすぐに、ユーザーに再確認してもらいたい場合があります。

  • ui_dialogアクションの詳細を読む
  • 選択した値を表示し、ユーザーに選択の確認を求めるダイアログをコンポーネントに追加します。

ワークフローのダウンロード(事前割り当て)

ヘルプ& リソース

  • 割り当て 2 では、オプションに<command>ui_dialog反応する新しいルールを作成する必要があります。既存のルールのロジックの一部は、その新しいルールに移動する必要があります。

解決

コンポーネントのダウンロード(課題後)

これで、4 回目のレッスンは終了です。第 5 回では、XML のみでワークフローを定義する場合のいくつかの制限と、ワークフローで JavaScript を使用してこれらの問題を解決する方法を検討します。