手机版

利用策略模式和装饰模式扩展JavaScript表单验证功能

时间:2021-09-06 来源:互联网 编辑:宝哥软件园 浏览:

简单表单验证

Html结构

!validata.html!doctype html lang=' en ' head meta charset=' utf-8 ' title validata/title/head body form id=' form ' label for=' username '帐号:/Labelinput id=' username ' type=' text ' br label for=' password ' password:/label id=' password ' br label for=' phonenum '手机:/Labelinput id=' phonenum ' type=' text ' br input id=' submit ' type=' button ' value=' submit '/form p id

首先,简单地实现以下功能

然后用设计图案丰满起来

//validata . jsvar form=document . getelementbyid(' form '),warn=document . getelementbyid(' warn ');varvalidata=function(){ if(form . username . value==' '){ return warn . text content='帐号不能为空';} if (form。password . value==' '){ return warn . text content=' password不能为空';} if (form。phone num . value===' '){ return warn . text content='手机号码不能为空';} var msg={ username : form . username . value,password : form . password . value,phone num 3360 form . phone num . value }//Ajax(' . ',味精);Ajax提交数据稍微返回warn.textContent='用户信息已成功提交到服务器';} form . submit . onclick=function(){ validata();}然后分析以下代码

validata函数没有可重用性,除此之外还有两个问题

该功能同时承担验证和提交两项职责。验证功能扩展性差,违反单一责任原则。如果要添加验证规则,必须深入函数,这违反了开闭原则,所以需要改进

装饰模式重构

首先,使用装饰模式解决功能的多重责任问题

方法也很简单

完善AOP预装修功能(功能.原型.以前)

当扩展函数(beforeFn)返回false时,不执行当前函数

然后将表单验证功能作为表单提交功能的前置装饰

这样,在提交之前会进行验证,如果验证失败,则不会提交数据

var form=document . getelementbyid(' form '),warn=document . getelementbyid(' warn ');function . prototype . before=function(Beforefn){ var self=this;return function(){ if(Beforefn . apply(this,arguments)==false)返回;返回self.apply(这个,参数);} }//改进的AOP预装饰函数varvalidata=function () {if (form。username . value==' '){ warn . text content='帐号不能为空';返回false} if (form。密码。value==='') {warn。textcontent=“密码不能为空”;返回false} if(form . phone num . value==' '){ warn . text content='手机号码不能为空';返回false}}var submitMsg=function(){ //从validata函数中提取提交的函数。var msg={ username : form . username . value,password : form . password . value,phone num 3360 form . phone num . value }//Ajax(' . ',味精);返回warn.textContent=“用户信息已成功提交到服务器”;} SubmItmsg=SubmItmsg . before(validata);//让表单验证功能成为表单提交功能表单的装饰器。submit . onclick=function(){ submit msg();};政策模式的重构

下面是解决功能缺乏弹性的问题

使用策略模式需要策略对象/类和环境对象/类

毫无疑问,检查规则应该安装在策略对象中

考虑到页面可能有多个验证表单。

最好用工厂级的形式写

完整的代码如下

var form=文档。getelementbyid(' form '),warn=document。getelementbyid(' warn ');功能。原型。before=function(Beforefn){ var self=this;返回函数(){ if(Beforefn。应用(这个,参数)==假)返回;返回self.apply(这个,参数);}}var vldStrategy={ //策略对象-验证规则isNonEmpty:函数(值,警告消息){ //输入不为空如果(值===' ')返回警告消息;},isLongEnough:函数(值、长度、警告消息){ //输入足够长if(值.长度长度)返回警告消息;},isShortEnough:函数(值、长度、警告消息){ //输入足够短if(值.长度长度)返回警告消息;},isMobile:函数(值,警告消息){ //手机号验证var reg=/^1[3|5|8][0-9]{9}$/;if(!reg.test(值))返回警告消息;}}var Validator=function(){ //环境类这个。规则=[];//数组用于存放负责验证的函数};验证器。原型。add=function(DOM节点,ruleArr){ //添加验证规则var self=这个;对于(var i=0,规则;rule=rule arr[I];){(函数(规则){ var strategyArr=rule。策略。拆分(' : '),警告消息=规则。警告消息;自我。规则。push(function(){ var tempArr=strategy arr。concat();var规则名称=Temparr。shift();坦帕尔。unshift(DomNode。值);坦帕尔。推送(警告消息);返回策略规则名]。应用(domNode,tempArr);});})(规则);}退回这个;};验证器。原型。start=function(){//开始验证表单对于(var i=0,vldFnvldFn=这个。规则[I];){ var warmsg=vldFn();if(警告消息){ warn。textcontent=warn msg返回false } } } var vld=new Validator();vld.add(form.username,[ { strategy: 'isNonEmpty ',warnMsg: '账号不能为空},{ strategy : '够长了:4 ',warnMsg: '账号不能小于四位},{ strategy : '不够:20 ',warnMsg: '账号不能大于20位' }]).添加(form.password,[ { strategy: 'isNonEmpty ',warnMsg: '密码不能为空' }]).add(form.phonenum,[{ strategy : '是一个空的',warnMsg: '手机号不能为空},{ strategy: 'isMobile ',warnMsg: '手机号格式不正确' }]);var submit msg=function(){ var msg={ username : form。用户名。值,密码:形式。密码。值,电话号码3360形式。电话号码。value }//Ajax('.味精);返回warn.textContent='用户信息已成功提交至服务器;} SubmItmsg=SubmItmsg。之前(vld。开始吧。绑定(vld));形式。提交。onclick=function(){ SubmItMSg();};//这里只是模拟提交,实际应该用表单。提交时

问题分析

总结一下易错的地方还有我敲得时候遇到的问题

验证器。原型。add=function(DOM节点,RuleArr){ var self=this;对于(var i=0,规则;rule=rule arr[I];){(函数(规则){ var strategyArr=rule。策略。拆分(' : '),警告消息=规则。警告消息;自我。规则。push(function(){ var tempArr=strategy arr。concat();var规则名称=Temparr。shift();坦帕尔。unshift(DomNode。值);坦帕尔。推送(警告消息);返回策略规则名]。应用(domNode,tempArr);});})(规则);}退回这个;};在验证器原型链上的增加函数需要注意几个问题

首先添加生活立即执行函数解决闭包问题就不用多说了

函数内又嵌套了函数,导致了这被劫持,所以必须缓存这

var self=这个;

最开始我没有拷贝这个数组而是直接使用的战略

验证器。原型。add=function(DOM节点,ruleArr){ //添加验证规则var self=这个;对于(var i=0,规则;rule=rule arr[I];){(函数(规则){ var strategyArr=rule。策略。拆分(' : '),警告消息=规则。警告消息;自我。规则。push(function(){//var tempArr=strategy arr。concat();var规则名称=strategyarr。shift();战略。unshift(domnode。值);战略。push(warmsg);返回策略规则名]。应用(domNode,strategyArr });})(规则);}退回这个;};第一次提交没有问题,但再次提交就会报错

这是因为第一次提交后,闭包中的战略已经改变

提交后,对该数组的操作不是预期的结果

我在这个地方犯了一个小错误,导致我在断点处调试了很长时间_ _ rz

validator . prototype . start=function(){//开始验证(var i=0,vldFnvldFn=this . rules[I];){ var warmsg=vldFn();if(warn msg){ warn . textcontent=warn msg;返回false}}}更正前的错误代码是这样的

validator . prototype . start=function(){//开始验证(var i=0,vldFnvldFn=this . rules[I];){ var warmsg=vldFn();if(warn msg)warn . textcontent=warn msg;返回false}}没错,只是因为少了一层大括号

可能之前只有一行,后来加return false的时候忘记加了

为了简洁起见,我这里不写花括号

我们通常不会这样写代码,只是自己挖坑,自己跳

submit msg=Submit msg . before(vld . start . bind(vld));注意添加装饰师的地方

如果不编写bind,就会发生这种劫持,并且还会报告一个错误

以上是使用策略模式和装饰器模式扩展JavaScript表单验证功能的介绍。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

版权声明:利用策略模式和装饰模式扩展JavaScript表单验证功能是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。