策略模式

发布时间 2023-12-14 18:34:38作者: lijun12138

定义策略

// 校验方法&规则配置
var strategies = {
  isNonEmpty: function( value, errorMsg ){ // 不为空
      if ( value === '' ){
          return errorMsg ;
      }
  },
  minLength: function( value, length, errorMsg ){ // 限制最小长度
      if ( value.length < length ){
          return errorMsg;
      }
  },
  isMobile: function( value, errorMsg ){ // 手机号码格式
      if ( !/(^1[3|5|8][0-9]{9}$)/.test( value ) ){
          return errorMsg;
      }
  }
};

 

 

定义校验器

// 校验执行器
var Validator = function(){
  this.cache = []; // 保存校验规则
};

 

 

定义校验器执行函数

Validator.prototype.add = function( dom, rule, errorMsg ){

  var ary = rule.split( ':' ); // 把strategy 和参数分开
  this.cache.push(function(){ // 把校验的步骤用空函数包装起来,并且放入cache
      var strategy = ary.shift(); // 用户挑选的strategy
      ary.unshift( dom.value ); // 把input 的value 添加进参数列表
      ary.push( errorMsg ); // 把errorMsg 添加进参数列表
      return strategies[ strategy ].apply( dom, ary );
  });
};

Validator.prototype.start = function(){
  for ( var i = 0, validatorFunc; validatorFunc = this.cache[ i++ ]; ){
      var msg = validatorFunc(); // 开始校验,并取得校验后的返回信息
      if ( msg ){ // 如果有确切的返回值,说明校验没有通过
          return msg;
      }
  }
};

 

 

校验器使用

// 控制器
var validataFunc = function(){
  var validator = new Validator(); // 创建一个validator 对象
  /***************添加一些校验规则****************/
  validator.add( registerForm.userName, 'isNonEmpty', '用户名不能为空' );
  validator.add( registerForm.password, 'minLength:6', '密码长度不能少于6 位' );
  validator.add( registerForm.phoneNumber, 'isMobile', '手机号码格式不正确' );
  var errorMsg = validator.start(); // 获得校验结果
  return errorMsg; // 返回校验结果
}

 

 

参考组件库

Validator.prototype.bindData = function(data) {
  this.data = data
}

Validator.prototype.addField = function(name, rule, errorMsg) {
  var that = this
  this.validateList[name] = function() {
    var ary = rule.split( ':' ); // 把strategy 和参数分开
    var strategy = ary.shift(); // 用户挑选的strategy
    ary.unshift( that.data[name] ); // 把input 的value 添加进参数列表
    ary.push( errorMsg ); // 把errorMsg 添加进参数列表
    return strategies[strategy](...ary)
  }
}
Validator.prototype.validateAll = function() {
  var that = this
  return new Promise(function(resolve, reject) {
    var validateList = Object.values(that.validateList)
    for(var i = 0; i < validateList.length; i++) {
      var result = validateList[i]();
      if(result){
        return reject({errorMsg: result});
      }
    }
    resolve(true)
  })
}
Validator.prototype.validateFields = function(...rest) {
  var fieldList = rest;
  var validateList = this.validateList
  return new Promise(function(resolve, reject) {
    if(!fieldList.length) {
      return reject('缺少参数字段')
    }
    for(var i = 0; i < fieldList.length; i++) {
      var result = validateList[fieldList[i]]();
      if(result){
        return reject({errorMsg: result});
      }
    }
    resolve(true)
  })
}

使用

var validator = new Validator();
var data = {};
validator.bindData(data);
data.name = "abc";
console.log(validator.data)
validator.addField( 'name', 'isNonEmpty', '用户名不能为空' );
validator.addField( 'password', 'minLength:6', '密码长度不能少于6位' );
validator.addField( 'phone', 'isMobile', '手机号码格式不正确' );
data.name = "abc";
data.password = "jbbjgg"
data.phone = "15993720858"
validator.validateAll().then(function(res) {
  console.log(res)
}).catch(function(error) {
  console.log(error)
})
validator.validateFields('phone').then(function(res) {
  console.log(res)
}).catch(function(error) {
  console.log(error)
})