使用策略模式校验表单
还在使用if else 校验表单?每次增加字段都要加 if,编码体验实在太差,快来使用策略模式
策略模式的主要思路是,定义一些策略,一般存到对象里面(策略池),然后需要使用哪种策略方法,就在需要的地方调用。
举个例子:策略池好比一个工具箱,工具箱里面放了一些工具(螺丝刀,扳手,锤子),需要用什么工具就用什么工具,想要修娃娃就用螺丝刀,修水管就用扳手,打boss就用锤子。还可以自己添加工具放入工具箱,缺把菜刀就定义一把菜刀放到工具箱,下次想打测试就可以用菜刀了。
// 对象字面量
var strategies = {
isNonEmpty: function(value, errorMsg) {
if (value === '') {
return errorMsg;
};
},
maxLength: function(value, length, errorMsg) {
if (value.length > length) {
return errorMsg;
};
},
isMobile: function(value, errorMsg) {
if (!/(^1[2||3|5|7|8][0-9]{9}$)/.test(value)) {
return errorMsg;
};
},
isSpace: function(value, errorMsg) {
if([...value].every( item => {
return item === ' ';
})) {
return errorMsg;
};
}
};
// 校验表单类
var Validator = function(strategies) {
if(this instanceof Validator) {
this.catch = [];
this.strategies = strategies;
} else {
return new Validator(streategies);
}
};
Object.assign(Validator.prototype, {
addRule: function(key, fn) {
this.strategies[key] = fn;
},
add: function(dom, rules) {
console.log("dom", dom);
var _self = this;
for (var i = 0, rule; rule = rules[i++]; ) {
(function(rule) {
var ary = rule.strategy.split(':');
_self.catch.push(function() {
var strategy = ary.shift();
ary.unshift(dom.value);
ary.push(rule.errorMsg);
return strategies && strategies[strategy] && strategies[strategy].apply(dom, ary);
});
})(rule);
};
},
start: function() {
for (var i = 0, validatorFunc; validatorFunc = this.catch[i++]; ) {
var msg = validatorFunc();
if (msg) {
return msg;
};
};
}
});
// 校验方法封装
var validataFunc = function() {
var validator = new Validator();
validator.add(registerFrom.name, [{
strategy: 'isSpace',
errorMsg: '请输入用户名'
},{ // 冒号 :分隔传值给策略函数
strategy: 'maxLength:10',
errorMsg: '用户名长度不能超过10个字符!'
}]);
validator.add(registerFrom.phone, [{
strategy: 'isMobile',
errorMsg: '手机号码格式不正确'
}]);
validator.add(registerFrom.address, [{
strategy: 'isSpace',
errorMsg: '请输入地址'
}]);
var errMsg = validator.start();
return errMsg;
};
var registerFrom = $('.form-box').get(0)
$('.submit').click(function() {
// TODO: 数据校验
var errorMsg = validataFunc()
if(errorMsg) {
weui.topTips(errorMsg)
return false
}
// 其他逻辑代码
}
精简版
公司的旧angulajs1.x版本的项目表单校验全是 if-else
,太难受了,重构
// 校验策略
var strategies = {
isNonEmpty: function(value, errorMsg) {
if (/^\s*$/g.test(value)) {
return errorMsg;
}
},
};
// 校验表单类
function Validator() {
// 缓存
this.catch = [];
}
angular.extend(Validator.prototype, {
add: function(value, rules) {
var _this = this;
for (var i = 0, rule; (rule = rules[i++]); ) {
(function(rule) {
var arr = rule.strategy.split(':');
_this.catch.push(function() {
var strategy = arr.shift();
arr.unshift(value);
arr.push(rule.errorMsg);
return strategies && strategis[strategy] && strategis[strategy].apply(null, arr);
});
})(rule);
}
},
start: function() {
for (var i = 0, validatorFunc; (validatorFunc = this.catch[i++]); ) {
var msg = validatorFunc();
if (msg) {
return msg;
}
}
},
});
// 校验方法
function validatorFunc() {
var vlidator = new Validator();
validator.add(merchantName, [{
strategy: 'isNonEmpty',
errorMsg: '请上传营业执照名称'
}])
return validator.start();
}
// 保存并下一步
$scope.nextFun = function() {
// TODO: isDebug 使用策略模式校验,不要再写if else了,受不鸟
var errorMsg = validataFunc();
if(errorMsg) {
weui.topTips(errorMsg);
return;
}
}