Às vezes, durante o desenvolvimento do fluxo de trabalho, as ferramentas que discutimos até agora não serão suficientes para implementar a lógica necessária. Normalmente, isso ocorre sempre que você precisa manipular os dados brutos de entrada, por exemplo, antes de compará-los em uma expressão ou antes de salvá-los em uma variável de contexto. Nesses casos, a opção de usar nosso mecanismo JavaScript incorporado (JS) na marcação do fluxo de trabalho deve oferecer uma solução viável.

Qualquer uso de JavaScript em um fluxo de trabalho deve estar sempre dentro de uma <![CDATA[ ... ]]> tag para evitar erros do analisador XML. Um escopo JS é aberto e fechado usando ?{ ... }?o . Você pode acessar variáveis de contexto de dentro do escopo JS usando context.variable_nameo . Para acessar os dados do evento, você também usaria, por exemplo: event.field

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

Como você pode ver no exemplo acima, você pode escrever JSs nativos arbitrários. Isso também pode abranger várias linhas e manuseio mais complexo. Você verá mais alguns exemplos no próximo artigo.

Funções incorporadas

Há algumas funções incorporadas que você pode usar diretamente no XML do fluxo de trabalho sem abrir um contexto JS. Alguns desses exemplos são usados regularmente em casos de uso específicos:

  • existe: existe(#{prateleira})
  • toUppercase: toUppercase( '#{material_name}' )
  • toLowermin: toLowermin( '#{material_name}')
  • trim: trim( #{material_name} )
  • contém: contém( #{first_code}, #{second_code})
  • startsWith: startsWith( #{first_code}, #{second_code})
  • endsWith: endsWith( #{first_code}, #{second_code})
  • igual: igual( #{first_code}, #{second_code})
  • substring: substring( #{material_name}, 0, 3)

O exemplo abaixo contém as toUpperCasefunções ,trim, e substring .

<rule id="speak_material">
    <expressão><![ 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>

O exemplo acima é típico, porque os comandos de fala sempre são emitidos em todas as letras maiúsculas. Se você quiser comparar um comando de fala com algum conteúdo em seu fluxo de trabalho, você deve sempre transformá-lo em maiúsculas também.

Dicas & truques: Não use espaço em branco para melhor legibilidade do código dentro de uma param tag do tipo string, pois ela se tornaria parte da string que você está manipulando. Por exemplo, resultaria em, por exemplo  MAT_<param name="material_type" type="string">trim(substring(#{material_name}, 0, 3)) </param> (onde _ é espaço em branco) mesmo que você tenha usado corte.

Exemplo

Vejamos mais alguns exemplos de casos de uso em que o mecanismo JS é útil:

Acessando dados dinamicamente

Às vezes, você precisa acessar dados dinamicamente (com base no conteúdo de outra variável de contexto):

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

Manipulação condicional de dados

Embora você também possa criar várias ações e regras para implementar isso, o JS permite brevidade:

    <setvar id="set_text_color"><context_update>
        
            <param name="label_text_color" type="string"><![ CDATA[ ?{ (contexto.urgente)? 'vermelho' : 'preto' }? ]]></param>
        </context_update>
    </setvar>

Geração e manipulação de objetos

JavaScript também ajuda você a gerar ou manipular objetos. No exemplo abaixo, queremos permitir que o trabalhador use comandos de fala para expressar uma quantidade de 0 a 99. Cada comando de fala precisa ser adicionado à gramática de fala separadamente, mas usando JavaScript podemos encurtar isso para:

<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="modificação">add_commands</param>
</ação>

Em expressões

Há também casos de uso em que JS ajuda em expressões. No exemplo abaixo, processamos um evento que é emitido quando um dispositivo de terceiros é desconectado. Usamos JS para pesquisar uma sequência de endereços MAC para o MAC do dispositivo desconectado.

<rule id="device_vanished"><
    expressão><![ CDATA[ #{event:command}== 'DEVICEVANISHED' && ?{ context.mac.search(event.mac)>-1}?]] ></expressão>
    <ações>
        <ação ref="back_to_start"/>
    </ações><
/regra>

Nota: O uso de JavaScript é limitado para expressões. O conteúdo de todas as expressões será cortado para remover todas as quebras de linha e espaços em branco que possam quebrar a lógica. Portanto, você não pode usar várias linhas de JavaScript em expressões.

Widget curinga

Outro caso de uso típico para JS é o widget curinga . Como ainda não introduzimos o lay-outing, não veremos um exemplo aqui, mas a documentação do widget tem um.

📌Designação

Na versão atual do nosso componente, a saída de nossa escolha é toda maiúscula e é mostrada como tal na interface do usuário do próximo componente. Vamos fazer com que pareça um pouco mais agradável:

  • Use JavaScript ou funções incorporadas para salvar a escolha resultante em um maiúsculo mais natural.

 Componente de Download (Pré-Atribuição)

Solução

Abaixo está uma solução exemplar:

<rule id="choice_made">
    <expressão><![ 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>  

 Componente de Download (Pós-Atribuição)

Na próxima lição, finalmente veremos como projetar a interface do usuário de um componente.