使用简单的状态机创建干净且健壮的 UI

实现一个简单的 JavaScript 状态机[每日前端夜话0xBF]

使用状态机可以构建健壮的 UI,其好处已有详细的描述—— 例如你可以参见Edward J. Pring 的文章和 David Khourshid 的视频。另外Krasimir Tsonev 描述了 JavaScript 中状态机的一些常用方法。一些比较流行的 JavaScript 库是 jakesgordon/javascript-state-machine 和 davidkpiano/xstate 。

在本文中,我将实现一个用于 JavaScript UI 的简单的状态机。为了保持内容简洁,我使用了 jQuery。

经典十字旋转门问题

状态机的经典 “Hello,World” 示例是 Turnstile。以下步骤描述了怎样把状态机应用于十字旋转门问题:

步骤1:编写状态转换表如:


实现一个简单的 JavaScript 状态机[每日前端夜话0xBF]

步骤2:捕获数据结构中的状态:


 1const turnstileStates = { 2  defaultState : function() { 3    $("#thankyou").hide(); 4    $("#cointxt").val(""); 5    $("#push").prop("disabled", true); 6    $("#cointxt").prop("disabled", false); 7    $("#turnstile_locked").show(); 8    $("#turnstile_unlocked").hide(); 9    $("#coinerrmsg").hide();10  },11  coinSuccessState : function() {12    $("#turnstile_locked").hide();13    $("#cointxt").prop("disabled", true);14    $("#push").prop("disabled", false);15    $("#coin").prop("disabled", true);16    $("#turnstile_unlocked").show();17    $("#coinerrmsg").hide();18  },19  coinErrorState : function() {20    $("#thankyou").hide();21    $("#cointxt").prop("disabled", false);22    $("#push").prop("disabled", true);23    $("#turnstile_locked").show();24    $("#coinerrmsg").show();25    $("#turnstile_unlocked").hide();26  },27  pushSuccessState : function() {28    $("#thankyou").show();29    $("#welcome").hide();30    $("#cointxt").prop("disabled", true);31    $("#turnstile_locked").hide();32    $("#coin").prop("disabled", true);33    $("#push").prop("disabled", true);34    $("#turnstile_unlocked").hide();35    $("#coinerrmsg").hide();36  }37};

注意,可以通过重构上面的函数体,来使用适当的数据参数调用类似 renderComponent() 的方法。我在这里用了详细模式,因此读者可以在一个地方快速看到 turnstileStates 配置背后的概念。

在这个 “Hello,World” 示例中,我没有使用来自于服务器的任何数据(模型)。当我们从服务器获得这样的模型时,turnstileStates 结构中的函数可以存在一个模型参数。

步骤3:捕获事件和事件处理


 1const turnstileEvents = { 2  coinEvent : { 3    handleCoin : function(e) { 4      if (e.data.coinval() > 0) { 5        return turnstileEvents.coinSuccessEvent; 6      } else { 7        return turnstileEvents.coinErrorEvent; 8      } 9    }10    //nextState not needed for this event11  },12  coinSuccessEvent : {13    nextState : function() {14      return turnstileStates.coinSuccessState();15    }16    //no handlers are needed for this event17  },18  coinErrorEvent : {19    nextState : function() {20      return turnstileStates.coinErrorState();21    }22    //no handlers are needed for this event23  },24  pushEvent : {25    handlePush : function() {26      return turnstileEvents.pushSuccessEvent;27    }28    //nextState not needed for this event29  },30  pushSuccessEvent : {31    nextState : function() {32      return turnstileStates.pushSuccessState();33    }34    //no handlers are needed for this event35  }36};

注意:nextnate 属性用于 turnstileEvents 配置而不是 turnstileStates 配置,因为我们在状态转换表中看到事后指示的下一个状态应该是什么。

步骤4:编排控制器中的状态和事件(在我们的例子中是 jQuery body):

 1//handle the page load event 2turnstileStates.defaultState(); 3//handle the coin event 4$("#coin").on("click",{ coinval : function(){return $("#cointxt").val();} },function(event) { 5  return turnstileEvents.coinEvent.handleCoin(event).nextState(); 6}); 7//handle the push event 8$("#push").click(function() { 9  return turnstileEvents.pushEvent.handlePush().nextState();10});

你可以查看本例的在线演示(https://mapteb.github.io/js-state-machine/jqueryStateMachineDemo.html),其中可以测试四个状态转换。该演示的完整源代码可在 GitHub 上找到。

结论

值得注意的是,用于 Java 程序的方法同样适用于JavaScript 程序。这个方法的一个特别之处在于三个组件中的关注点的清晰分离 —— 状态、事件/事件处理handler和控制器。总之,把状态机用于前端应用能够有助于构建干净且健壮的 UI。
原文:https://dzone.com/articles/a-simple-javascript-state-machine

更多相关文章

  1. js和jquery使按钮失效为不可用状态的方法
  2. 如何在进度条全屏表单界面上添加百分比状态
  3. 如何用jQuery获取django的HttpResponse状态码?
  4. jquerymobile phonegap back按钮获取先前状态
  5. HTML新手求解。关于CSS对于li标签的active状态的背景颜色
  6. html5中点击按钮,改变按钮状态效果样式
  7. 更改在表Django中选择了其中一个按钮时显示的状态
  8. C 实现HTML5服务时,遇到握手状态的判断问题...
  9. jQuery更改活动类图标的状态

随机推荐

  1. 如何在MVC4中使用type= " url "而不用jQu
  2. jquery.min.js引入项目报错
  3. JQuery攻略(三)数组与字符串
  4. jsf中获取属性值的普通获取和jquery获取
  5. jQuery中filter()和find()的区别深入了解
  6. 有关下拉框jquery里的change事件无法触发
  7. 使用AJAX将动态数据传递给mvc控制器
  8. jquery.countdown 倒计时插件的学习
  9. jQuery ajax问题 - 无法让我的函数工作
  10. JQuery 表单验证按钮提交之前变色