Метаязык для определения рабочего процесса HTML-приложения

#javascript #extjs #workflow #metalanguage

#javascript #extjs #рабочий процесс #метаязык

Вопрос:

Я ищу способ, чтобы язык независимо выражал рабочий процесс HTML-приложения. Если пользователь вводит определенные значения в форму, должна отображаться другая форма. Далее, если значения заполнены, в этих дочерних формах должны быть показаны новые части этих дочерних форм.

Я хочу выразить отношения между HTML-формами, HTML-элементами в этих формах и значениями этих элементов.

На основе информации базы данных, такой как поля таблицы и связи между таблицами, которыми я управляю с помощью Doctrine, я создаю формы ExtJS.

Теперь мне нужно ввести некоторую логику потока в мои ExtJS-формы таким образом, чтобы я не жестко кодировал поток приложения с помощью кода ExtJS (JavaScript) напрямую.

Я хочу сгенерировать соответствующий код JavaScript во время выполнения на основе предопределенного файла конфигурации.

Например:

У меня есть X forms

 FORM 1. (displayed on startup)
 |
 |-> FROM 1.1 (only display after values have been inserted into FORM 1.)
 |
 |-> FROM 1.2 (only display after values have been inserted into FROM 1.1)
 |
FROM 2. (display when something inserted into FORM 1.)
 |
 |-> FROM 2.1 (layout and elements of this form depend upon what has been 
     inserted into FROM 1.)
 ....  
  

Кроме того, я хочу отображать части форм только в том случае, если пользователь что-то заполнил в поле ввода

 FORM 1. (displayed on startup)
 |
 |-> LAYER 1. (only display/activate after field <count> of FROM 1. 
 |   has been filled in)
 |
 |-> LAYER 2. (only display/activate after field <count> of LAYER 1. 
 |   has been filled in)
 |
 ....
  

Тогда я хочу отображать формы, только если значение, которое пользователь заполнил в элементе формы
передает предопределенное условие

 FORM 1 (displayed on startup)
 |
 |-> FROM 1.1 (only display if field <count> of FROM 1. is greater that 10
 |   count > 10)
 |
 |-> FROM 1.2 (if count < 10 display this form)
 |
 ....  
  

Последнее, что я хочу, на основе значений, которые пользователь вставил в родительскую форму, установить правила для входных элементов, чтобы ограничить их диапазон ввода (возможные значения)

Вот пример рабочего процесса

введите описание изображения здесь

Существует ли уже метаязык для определения подобных отношений?

Каким был бы ваш подход к реализации чего-то подобного?

С уважением,

J.

Ответ №1:

Что я бы сделал, так это начал с других инструментов / проектов, которые используют аналогичную настройку в другом домене, и посмотрел, сможете ли вы применить ее методы к своему собственному домену.

Например, взгляните на Cucumber (http://cukes.info /). Cucumber — это инструмент разработки, основанный на поведении, который предназначен для функционального тестирования приложения. Он использует понятный человеку тестовый синтаксис. Другой — Selenium (http://seleniumhq.org /), в котором интерактивность интерфейса описывается на языке, специфичном для домена.

Надеюсь, эти два дают вам некоторое вдохновение для вашего решения, удачи

Роб

Ответ №2:

прежде всего, спасибо @Rob за ваш ответ. Я, наконец, решил использовать пользовательское решение.

Поэтому я просмотрел некоторые другие реализации управления потоком javascript

А именно:

Поток
https://github.com/bemson/Flow/wiki/Flow-Use-Cases

Где вы можете определить поток приложений (порядок вызова функций javascript) в предопределенном синтаксисе.

Мне особенно понравилась идея функций предварительного и последующего состояния (_in и _out) в потоке, которые выполняются перед входом в состояние в потоке приложения и выходом из состояния. Кроме того, идея массива _vars, привязанного к определенному состоянию потока, была довольно интересной.

Смотрите https://github.com/bemson/Flow/wiki/Using-Flow#s3-1 для получения дополнительной информации.

Джеймс Макпарлейн разработал конечный автомат (FSM) на JavaScript, где он описал поток приложений в XML, а не в обычном JavaScript. Я нашел это хорошей идеей, но то, что он делает, — это анализирует XML на стороне клиента, а не на стороне сервера. Что для меня является недостатком.

В любом случае. Он описывает состояния, подобные этому

 <fsm>
  <states>
    <state name="Start">
      <enter call="initApp();" />
      <exit call="exitApp();" />
      <to>
        <from state="" call="displayStartPage();" />
        <from state="loggedOut" call="showLogoutMessage();displayStartPage();" />
       </to>
    </state>
    <state name="loggedIn">
      <include state="authenticated" />
      <exclude state="loggedOut" />
      <negate state="loggedOut" />
    </state>       
  </states>
</fsm>
  

Он использует следующие возможные теги

 <fsm>       ... the root node of the fsm (I renamed it to better reflect the purpose)
<states>    ... a collection of possible states (a state can have sub-states)
<state>     ... a possible state
<exclude>   ... if a state is active excluded one should be inactive
<include>   ... if a state is active the included state should also be active
<require>   ... should check that a javascript condition is true
<unrequire> ... the negation of <require>
<negate>    ... negate a state if you enter another state
<affirm>    ... make another state active, if entering a specific state
<enter>     ... fire a trigger when state gets active
<exit>      ... fire a trigger when state gets in-active
<from>/<to> ... specify state transitions and actions according to these transitions
<lock>      ... lock state, until state machine is reset
  

Кроме того, могут потребоваться некоторые удобные функции. Чтобы назвать представление:

 testState   ... to test the state of the FSM
negateState ... negate a state 
affirmState ... set a new state and issue according transition events
flipState   ... set state from active to inactive and vice versa 
determine   ... determine current state
  

Смотрите
http://blog.metawrap.com/2008/07/21/javascript-finite-state-machinetheorem-prover/
и

http://blog.metawrap.com/2008/09/25/practical-applications-of-finite-state-machines-in-web-development/
для получения дополнительной информации.

Некоторое другое решение, которое я нашел у Камило Азулы, представляет собой своего рода смесь между observer и шаблоном command.

http://camiloazula.wordpress.com/2010/10/14/fsm/

Где он использует именованные константы для определения состояний и уведомления наблюдателей об изменениях состояния.

Майкл Шуериг, писал на эту тему, но, к сожалению, его источников больше нет в Сети. В любом случае, его концепция основана на цепочке методов, как вы, вероятно, знаете это из jQuery и других фреймворков JS.

Наконец, у IBM также есть учебное пособие, посвященное этой теме

http://www.ibm.com/developerworks/library/wa-finitemach1/
http://www.ibm.com/developerworks/library/wa-finitemach2/
http://www.ibm.com/developerworks/library/wa-finitemach3/

Но, честно говоря, мне это не очень понравилось.

Прямо сейчас я погружаюсь в веб-поток Spring, который использует язык выражений Springs, который я нахожу очень интересным.

В любом случае мой конечный продукт будет основан на определении потока, аналогичном определению Джеймса Макпарлейна, но в отличие от его подхода я буду анализировать XML, который определяет поток приложения на стороне сервера.

На основе этого XML я прикреплю javascript к каждой странице (каждая страница имеет свой собственный XML), который содержит соответствующий поток приложений. Поскольку наша система основана на ExtJS, я буду использовать

http://docs.sencha.com/ext-js/4-0/#/api/Ext.EventManager-method-addListener

 addListener 
  

функция для управления потоком приложений на основе пользовательских событий.

Я надеюсь, что это поможет кому-нибудь в будущем.

С уважением

JS