使用策略模式校驗表單
還在使用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;
}
}