策略模式在表单验证中的应用
最近想要封装一个校验表单的方法,没有什么很优雅的解决思路。
今天偶然看到了这篇文章,学到了一种新的设计模式....
实现也很容易理解。原文很详细,非常感谢文章的指点
原文链接:策略模式在表单验证中的应用
作者: HcySunYang
代码
function FormValidation(VerifiPolicy) {
// 保存策略对象
this.strategies = VerifiPolicy
// 验证缓存
this.validationFns = []
}
FormValidation.prototype.add = function (dom, rule, errMsg) {
// 因为传入的是一个字符串,如'maxLength: 16',所以将其拆成数组方便操作
var ary = rule.split(':')
// 策略函数的参数
var arg = []
var self = this
this.validationFns.push(function () {
// 重置参数
arg = []
var ruleName = ary[0]
arg.push(dom.value)
// 组装参数
if (ary[1]) {
arg.push(ary[1])
}
arg.push(errMsg)
arg.push(dom)
// 调用策略函数
return self.strategies[ruleName].apply(dom, arg)
})
}
// 一键校验的方法
FormValidation.prototype.start = function () {
var msgs = []
for (var i = 0;i < this.validationFns.length; i++) {
var msg = this.validationFns[i]()
if (msg) {
msgs.push(msg)
}
}
if(msgs.length) {
return msgs
} else {
return 'success'
}
}
使用
<form class="wrapper">
<label for="">USERNAME</label><input type="text" name="username">
<br>
<label for="">PASSWORD</label><input type="text" name="password">
<br>
</form>
<button class="button">提交</button>
// 策略对象
var VerifiPolicy = {
// 判断是否为空
isNoEmpty: function (value, errorMsg, el) {
if (value == '') {
return {errorMsg, el}
}
},
// 判断最小长度
minLength: function (value, length, errorMsg, el) {
if (value.length < length) {
return {errorMsg, el}
}
},
maxLength: function(value, length, errorMsg, el) {
if(value.length > length) {
return {errorMsg, el}
}
},
// 判断是否为手机号
isMobile: function (value, errorMsg) {
if (!/(^1[3|5|8][0-9]{9}$)/.test(value)) {
return {errorMsg, el}
}
}
// 其他
}
var validation = new FormValidation(VerifiPolicy)
var form = document.querySelector('.wrapper')
validation.add(form.username, 'isNoEmpty', '用户名错误')
validation.add(form.password, 'minLength: 6', '密码太短')
validation.add(form.password, 'maxLength: 4', '密码太长')
document.querySelector('.button').onclick = function() {
var errmsg = validation.start()
console.log(errmsg)
}
/* (3) [{…}, {…}, {…}]
0: {errorMsg: "用户名错误", el: input}
1: {errorMsg: "密码太短", el: input}
2: {errorMsg: "密码太长", el: input}
length: 3
__proto__: Array(0) */
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。