Combining State Machine Development Style

Keywords: angular Windows less

Based on the HTML 5 version of XXX, this paper discusses the idea and practice of state machine development. Selection and Use of State Machine statechart.js.

Starting knowledge

Especially the introduction of state machine, the content is very good, strongly recommended.

Applicable scenario

  • Complex page flow control for a specific business
  • Simple business processes are not needed. For example, there are only one or two pages (list + details)
  • Suitable for multi-step, multi-page (including pop-up boxes) and various jump scenarios

How to define state?

Define state according to page flow and steps. Reference can be made to the following steps:

  • Comparing with fidelity and flow chart, divide each page into separate pages
    Take personal marketing activities as an example, the main pages include activity pages, grade pages, prize pages, prize package selection pages, payment pages, invoice pages.
    Then consider defining it as list, level, reward, giftpack, charge, invoice

  • For cases with multiple pop-up windows, you can consider defining sub-states
    Take the recommendation business as an example. On the menu page, a feedback window or a product order window may pop up.
    Consider defining menu/index, menu/feedback, menu/prod, so that menu pages can be displayed all the time in the case of value status by controlling the following pages.

<div ng-show="fsm.isCurrent('/menu')" ng-include="'app/partials/recommended/recommended_menu.html'"></div>
<div ng-show="fsm.isCurrent('/menu/prod')" ng-include="'app/partials/recommended/recommended_orderprod.html'"></div>
<div ng-show="fsm.isCurrent('/menu/feedback')" ng-include="'app/partials/recommended/recommended_feedback.html'"></div>
  • For pages with more common features, we can consider defining sub-states to facilitate sharing logic and event handling.
    Taking the above personal marketing activities as an example, the pages of prize pages and prize bag selection pages are very similar, and the functional operations are relatively implemented, which can be defined as sub-states, such as order/reward, order/giftpack.
<div ng-show="fsm.isCurrent('/list')" ng-include="'app/partials/personalMarketCamp/personalMarketCamp_list.html'"></div>
<div ng-show="fsm.isCurrent('/level')" ng-include="'app/partials/personalMarketCamp/personalMarketCamp_level.html'"></div>
<div ng-show="fsm.isCurrent('/order/reward')" ng-include="'app/partials/personalMarketCamp/personalMarketCamp_reward.html'"></div>
<div ng-show="fsm.isCurrent('/order/giftpack')" ng-include="'app/partials/personalMarketCamp/personalMarketCamp_giftpack.html'"></div>
<div ng-show="fsm.isCurrent('/invoice')" ng-include="'app/partials/personalMarketCamp/personalMarketCamp_invoice.html'"></div>
<div ng-show="fsm.isCurrent('/charge')" ng-include="'app/partials/personalMarketCamp/personalMarketCamp_charge.html'"></div>

How to control the display of the page and how to respond to the operation of the page?

  • Whether the page is displayed or not depends on the state of the state machine, not the state of the data. The isCurrent method is used here.
  • Page operations are sent through state machine events rather than directly using a method bound to $scope. The send method is used here.
  • Page jumps are driven by state machine changes. The goto method is used here, which is processed in event logic after the send method.

Whether the page is displayed or not, the example has been mentioned above. For the ng-click event triggering, the send method can be used directly.

<div class="Feedback-btn">
  <a ng-click="fsm.send('feedback', 'hesitate')" class="accept-btn"><span>Consider</span></a>
  <a ng-click="fsm.send('feedback', 'refuse')" class="refuse-btn"><span>refuse</span></a>
</div>

As you can see, events can also carry parameters, which can be processed in event of that state, as follows:

# feedback
@state 'feedback', ->
  # Feedback operation
  @event 'feedback', (operationtype) ->
    product = $scope.viewModel.product
    if product.opertype == '1'
      new Toast(
        context: $('body')
        message: "This product is not recommended."
      ).show();
      return

    qryfeedbackService.event
      "userseq": $scope.viewModel.product.userseq
      "servnumber": $scope.telnum
      "operationtype": operationtype
    .then (ok) =>
        @goto '/menu/index'
      , (err) ->
        new Toast(
          context: $('body')
          message: err
        ).show()

It should be noted that event is attached to a certain state. If you are in a child state, event will be found in the child state first, and if not in the parent state.
In this way, multiple sub-state sharing events can be realized, such as the prize page and the prize package page, which have the function of selection. This operation can be put into the event of the parent state.

More details about state machines

Many state machines implement some special states, such as entry state and exit state. statechart is also implemented, corresponding to enter and exit. The code is basically:

@state 'menu', ->
  @enter ->
    #TODO

  @exit ->
    #TODO

However, it should be noted that if you enter this state repeatedly, it will be repeated. So for a business process such as A-> B-> C, the enter is executed from A to B and C back to B.
It is impossible to distinguish between these situations. Because usually, from A to B initialization, and from C to B to retain the original B data state. So in fact, I seldom use these special events unless:

  • There is no need to distinguish between cases, so writing will make the code style more uniform.
  • No interface interaction, local operation, because this consumption is much less.
  • There is a case of jumping directly to that state (for example, by another business), in which the preceding steps are ignored. In this case, interface interaction (such as supplementing some necessary information) is usually required, and in order to distinguish between fallbacks, I usually consider some data caching processing based on business characteristics.

Posted by Pinkerbot on Tue, 26 Mar 2019 19:36:28 -0700