ワークフロー開発では、ここまで説明してきたツールでは、必要なロジックを実装するのに十分でない場合があります。通常、これは、生の入力データを操作する必要がある場合、たとえば、式で比較する前やコンテキスト変数に保存する前に発生します。このような場合、ワークフローマークアップに埋め込まれたJavaScript(JS)エンジンを使用するオプションは、実行可能なソリューションを提供するはずです。

ワークフローでの JavaScript の使用は、XML パーサーのエラーを回避するために、常にタグ内に <![CDATA[ ... ]]> 配置する必要があります。JS スコープは、 を使用して開いたり閉じたり ?{ ... }?します。コンテキスト変数には、JS スコープ context.variable_name内から .イベントデータにアクセスするには、 event.field次のようにします。

<setvar id="add_digit_from_speech_command"><context_of>
    workflow</context_of>
    <context_update>
        <param name="number" type="long"><![CDATA[ ?{ context.number + number(event.command.substr(event.command.length - 1, event.command.length)) }? ]]></param><
    /context_update>
</setvar です>

上記の例でわかるように、任意のネイティブJSを書くことができます。これは、複数の行にまたがり、より複雑な処理を行うこともできます。次の記事では、さらにいくつかの例を紹介します。

組み込み関数

JS コンテキストを開かずにワークフロー XML で直接使用できる埋め込み関数がいくつかあります。これらの例のいくつかは、特定のユースケースで定期的に使用されます。

  • exists: exists(#{shelve})
  • toUppercase: toUppercase( '#{material_name}' )
  • toLowercase: toLowercase( '#{material_name}')
  • trim: trim( #{material_name} )
  • contains: contains( #{first_code}, #{second_code})
  • startsWith: startsWith( #{first_code}, #{second_code})
  • 終了ウィズ: endsWith( #{first_code}, #{second_code})
  • 等しい: equals( #{first_code}, #{second_code})
  • 部分文字列: substring( #{material_name}, 0, 3)

次の例には、 とsubstring trim,  関数が含まれています。 toUpperCase

<ルールid="speak_material"><
    expression><![CDATA[ #{event:command} == toUpperCase('#{material_name}') ]]></expression>
    <actions>
        <setvar id="set_material_type">
            <context_update><
                param name="material_type" type="string">trim(substring(#{material_name}, 0, 3))</param>
            </context_update>
        </setvar><
    /actions><
/rule>

上記は典型的な例で、音声コマンドは常にすべて大文字で出力されるためです。音声コマンドをワークフロー内のコンテンツと比較する場合は、常に大文字に変換する必要があります。

ヒントとテクニック: コードを読みやすくするために、 型のstring タグ内で param は、操作している文字列の一部になるため、空白を使用しないでください。たとえば、trim を使用した場合でも、 <param name="material_type" type="string">trim(substring(#{material_name}, 0, 3)) </param> たとえば MAT_ (_ は空白) になります。

JSエンジンが役立つユースケースの例をいくつか見てみましょう。

データの動的アクセス

場合によっては、(別のコンテキスト変数の内容に基づいて)動的にデータにアクセスする必要があります。

    <setvar id="set_step">
        <context_update>
            <param name="step" type="object"><![CDATA[ ?{context.steps[context.current_step_index]}?]]></param>
        </context_update>
    </setvar です>

条件付きデータ操作

これを実装するために複数のアクションとルールを作成することもできますが、JSでは簡潔にすることができます。

    <setvar id="set_text_color"><context_update>
        
            <param name="label_text_color" type="string"><![CDATA[ ?{(context.urgent)ですか?'red' : '黒' }?]]></param><
        /context_update>
    </setvar>

オブジェクトの生成と操作

JavaScript は、オブジェクトの生成や操作にも役立ちます。以下の例では、ワーカーが音声コマンドを使用して 0 から 99 の量を表現できるようにします。各音声コマンドは音声文法に個別に追加する必要がありますが、JavaScript を使用すると、これを次のように短縮できます。

<action id="add_amount_speech_commands" type="speech_modify_commands_in_grammar"><
    param name="slot">wf_editor_slot</param>
    <param name="commands"><![CDATA[ ?{
        Array.apply(null, {length: 100})
             .map(Number.call, Number)
             .map(function(e) { 
                    return { 'name': 'AMOUNT ' + (e), 'description': 'AMOUNT [0-99]'}
                
        })}? ]]></param><
    param name="modification">add_commands</param><
/actionです>

In エクスプレッション

JSが式で役立つユースケースもあります。以下の例では、サードパーティのデバイスが切断されたときに発生するイベントを処理します。JSを使用して、切断されたデバイスのMACのMACアドレスの文字列を検索します。

<ルールid="device_vanished">
    <expression><![CDATA[ #{event:command}== 'DEVICEVANISHED' && ?{context.mac.search(event.mac)>-1}?]]></expression><
    actions><
        action ref="back_to_start"/>
    </actions><
/ruleです>

: JavaScript の使用は 、式では制限されています。すべての式の内容がトリミングされ、ロジックを壊す可能性のあるすべての改行と空白が削除されます。したがって、式で複数行の JavaScript を使用することはできません。

ワイルドカードウィジェット

JSのもう一つの典型的なユースケースは、ワイルドカードウィジェットです 。レイアウトアウトをまだ導入していないので、ここでは例を見ませんが、 ウィジェットのドキュメント にはあります。

📌割り当て

コンポーネントの現在のバージョンでは、選択した出力はすべて大文字であり、次のコンポーネントの UI にそのように表示されます。もう少し見栄えを良くしましょう。

  • JavaScript または埋め込み関数を使用して、結果の選択をより自然な大文字化で保存します。

 コンポーネントのダウンロード(事前割り当て)

解決

以下は、例示的な解決策です。

<ルールid="choice_made">
    <expression><![CDATA[ #{event:command} == 'APPLE' || #{event:command} == 'PEAR' ]]></expression>
    <actions>
        <setvar id="save_choice">
            <context_of>workflow</context_of>
            <context_update><
                param name="choice" type="string"><![CDATA[ ?{ event.command.slice(0,1) + event.command.slice(1).toLowerCase() }? ]]></param>
            </context_update>
        </setvar><
        action ref="show_confirmation_dialog"/>
    </actions><
/ruleです>  

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

次のレッスンでは、最後にコンポーネントのユーザーインターフェイスを設計する方法を見ていきます。