策略模式在表单验证中的应用

最近想要封装一个校验表单的方法,没有什么很优雅的解决思路。
今天偶然看到了这篇文章,学到了一种新的设计模式….
实现也很容易理解。
原文链接: http://hcysun.me/2016/02/21/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E5%9C%A8%E8%A1%A8%E5%8D%95%E9%AA%8C%E8%AF%81%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/
作者: HcySunYang

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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";
}
};

使用

1
2
3
4
5
6
7
<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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 策略对象
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) */