如何用js 实现依赖注入的思想,后端框架思想搬到前端来


大家在做些页面的时候,很多都是用ajax实现的,在显示的时候有很多表单提交的add或者update操作,显然这样很烦,突然想到了一个比较好的方法,下面给大家分享下如何用js 实现依赖注入的思想,后端框架思想搬到前端来。

应用场景: 前后端一一对应、表单内容保存、列表陈述等。

架构思路: 分发器、依赖注入等。

基本代码陈述:

j.extend({
 dispatcher: (function () {
  var _route = {},
   // default module
   _module = {
    // 授权
    authenticate: true,
    // 验证
    validation: true,
    // 数据转换
    dataTransform: true,
   },
   _state = {
    error: function () { }
   },
    _ajax = function () {
     j.ajax(this)
    }
  ;
  function _container() {
   // initializer.
   return _route;
  }
  function _configuration(config, _tmp_route) {
   if (config) {
    config.module && (_module = $.extend(_module, config.module))
    config.state && (_state = $.extend(_state, config.state))
    config.post && config.post.queryString && (function () {
     if (!/^\?/.test(config.post.queryString)) {
      _tmp_route += "?";
     }
     _tmp_route += config.post.queryString;
    })()
    config.list && (function () {
     config.list = $.extend({
      pageSize: 15,
      wrapped: $('#list-container'),
      searchForm: $('#form-post'),
      searchButton: $('#search-button'),
      post: {}
     }, config.list);
    })()
   }
   return _tmp_route;
  }
  return {
   ajax: new _container(),
   intercept: {
    module: function (module) {
     $.extend(true, _module, module);
    },
    route: function (route) {
     if (!$.isEmptyObject(_route)) return;
      $.extend(true, _route, route);
     for (var i in _route) {
      if (_route.hasOwnProperty(i)) {
       var _controller = _route[i];
       for (var k in _controller) {
        if (_controller.hasOwnProperty(k) && j.utils.isFunction(_controller[k])) {
         (function () {
          var clone = j.clone(_controller[k]), _tmp_route = '/' + i + "/" + k;
         _controller[k] = function (config) {
          var url = _configuration(config, _tmp_route);
          if (j.utils.isFunction(clone)) {
           clone.apply(_module, config);
          }
          // todo modules
          if (!(_module.authenticate && j.utils.isFunction(_module.authenticate)) && _module.authenticate() || _module.authenticate === true) {
           console.log('j.ajax.' + i + "." + k + " authenticate failed.");
           config.state.error();
           return false;
          }
          if (config.validation) {
           _module.validation.init(config.validation);
           config.validation.fireTarget.on('click', function () {
            if (!_module.validation || !config.validation.formTarget.valid())
             return false;
            var data = _module.dataTransform(!config.post.data ? config.validation.formTarget.serializeJson() : config.post.data)
            var ajax_data = {
             url: url,
             data: data,
             fireTarget: config.validation.fireTarget
            }
            ajax_data = $.extend(ajax_data, config.post);
            _ajax.call(ajax_data);
            return false;
           })
          }
          if (config.list) {
           if (!$.fn.pagination) {
            throw new Error('j.dispatcher.intercept.list need jQuery.pagination,please load jQuery.pagination before this file.')
           }
           config.list.onChange = function (pageIndex) {
            var $this = this;
            this.showLoading();
            var formData = config.list.searchForm.serializeJson();
            formData.pageIndex = pageIndex;
            formData.pageSize = $this.pageSize;
            var data = _module.dataTransform(!config.list.post.data ? formData : config.list.post.data)
            var ajax_data = {
             url: url,
             data: data,
            }
             $.extend(true, ajax_data, config.list.post);
            ajax_data.success = function () {
             $this.generateData(this.totalRecords, this.list);
            }
            j.jsonp(ajax_data)
           }
           j.list.table(config.list);
           config.list.searchButton.on('click', function () {
            config.list.wrapped.empty();
            j.list.table(config.list);
           })
          }
         }
         }())
        }
       }
      }
     }
    }
   }
  }
 })()
})
var global = {
 dataTransform: {
  "default": function () {
   if (typeof (arguments[0]) == "object" && Object.prototype.toString.call(arguments[0]).toLowerCase() == "[object object]" && !arguments[0].length) {
    return j.json.toKeyValString(arguments[0],true);
   }
   else if (j.utils.isString(arguments[0])) {
    return arguments[0];
   }
   else {
    return {};
   }
  },
  "objectData": function () {
   if (typeof (arguments[0]) == "object" && Object.prototype.toString.call(arguments[0]).toLowerCase() == "[object object]" && !arguments[0].length) {
    return { data: j.json.toString(arguments[0]) }
   }
   else if (j.utils.isString(arguments[0])) {
    return arguments[0];
   }
   else {
    return {};
   }
  }
 }
}
j.dispatcher.intercept.module({
 authenticate: function () {
 },
 validation: (function () {
  var hasCongfig = false;
  function _config() {
   if (!$.fn.validate) {
    throw new Error('j.dispatcher.intercept.module.validation need jQuery.validate,please load jQuery.validate before this file.')
   }
   jQuery.validator.addMethod("isPassword", function (value, element) {
    return j.config.reg_phone.test(value);
   }, "请输入6-20密码建议由数字、字母和符号组成!");
   jQuery.validator.addMethod("isMobile", function (value, element) {
    return j.config.reg_phone.test(value);
   }, "请正确填写您的手机号码");
   jQuery.validator.addMethod("isEamil", function (value, element) {
    return j.config.reg_email.test(value);
   }, "请填写正确的邮箱地址");
   jQuery.validator.addMethod("isUserName", function (value, element) {
    return j.config.reg_login_name.test(value);
   }, "4-32位字符.支持汉字、字母、数字\"-\"\"_\"组合");
  }
  function _getRequired(parms, filters) {
   if (parms instanceof jQuery && parms.length > 0 && parms[0].tagName == 'FORM') {
    var config = {};
    parms.find('[name]').each(function () {
     if (!filters || filters.indexOf(this.name) == -1) {
      config[this.name] = { required: true };
     }
    })
    return config;
   }
   else {
    for (var i in parms) {
     if (parms[i]) {
      parms[i]['required'] = true;
     }
     else {
      parms[i] = { required: true };
     }
    }
    return parms;
   }
  }
  function _getMessage(parms, filters) {
   if (parms instanceof jQuery && parms.length > 0 && parms[0].tagName == 'FORM') {
    var config = {};
    parms.find('[name]').each(function () {
     if (!filters || filters.indexOf(this.name) == -1) {
      config[this.name] = { required: $(this).attr("data-required-message") };
     }
    })
    return config;
   }
  }
  function _init(config) {
   if (!hasCongfig) {
    hasCongfig = true;
    _config();
   }
   !config.formTarget && $('#form-post').length > 0 && (config.formTarget = $('#form-post'))
   !config.fireTarget && $('#post-button').length > 0 && (config.fireTarget = $('#post-button'))
   if (!(config.fireTarget && config.fireTarget instanceof jQuery && config.fireTarget[0].type.toUpperCase() == 'SUBMIT'))
    throw new Error("j.validator.init needs config.submitTarget param, its type is submit");
   if (!(config.formTarget && config.formTarget instanceof jQuery && config.formTarget[0].tagName == 'FORM'))
    throw new Error("j.validator.init needs config.formTarget param, its type is form");
   var rules = _getRequired(config.formTarget, config.filters), messages = _getMessage(config.formTarget, config.filters);
   config.rulesCallBack && config.rulesCallBack(rules);
   config.messagesCallBack && config.messagesCallBack(messages);
   config.formTarget.validate({
    debug: true,
    rules: rules,
    messages: messages
   });
  }
  return {
   init: function (config) {
    _init(config);
   },
   validate: function () {
    return config.formTarget.valid();
   }
  }
 })(),
 dataTransform: global.dataTransform.objectData
})
j.dispatcher.intercept.route({
 passport: {
  signin: function () {
   this.dataTransform = global.dataTransform.default;
  },
  signout: function () { },
  reg: function () { },
  cpwd: function () {
   this.dataTransform = global.dataTransform.default;
  }
 },
 company: {
  save: function () { },
  getList: function () { }
 },
 account: {
  save: function () { },
  saveProfile: function () { },
  getList: function () {
  }
 },
 partnership: {
  signup: function () {
  },
  getList: function () { }
 },
 venue: {
  getList: function () {
  save: function () { },
 },
 show: {
  save: function () { },
 }
});

比如list使用:

j.dispatcher.ajax.account.getList({
 list: {
  header: ['编号', '用户名', '账户类型', '公司类型', '注册时间', '最后登录时间', '是否启用', '操作'],
  rowField: ['AccountCode', 'AccountName', 'AccountType', 'CompanyType', 'RegisterTime', 'LastActivityTime', 'IsAvailable', function (item) {
   var html = '<a href="/account/sub?type=edit&id=' + item.Id + '" class="k-table-icon fa-edit mr15" title="编辑信息" ></a>'
      + '<a href="javascript:;" class="k-table-icon fa-trash" title="删除账户" onclick="operate(this,\'delete\',{ id : \'' + item.Id + '\' })"></a>'
   ;
   return html;
  }],
  formatColumn: function (item, data) {
   if (item.IsAvailable != undefined) {
    if (item.IsAvailable == true) {
     return '<a href="javascript:;" onclick="operate(this,\'set\',{ id : \'' + data.Id + '\',isEnable : 0 })" class="k-table-icon glyphicon glyphicon-ok-circle" title="已启用"></a>';
    }
    else
     return '<a href="javascript:;" onclick="operate(this,\'set\',{ id : \'' + data.Id + '\',isEnable : 1 })" class="k-table-icon c-error glyphicon glyphicon-ban-circle" title="已禁用"></a>';
   }
   else if (item.LastActivityTime) {
    var now = moment(item.LastActivityTime);
    return now.format('YYYY-MM-DD HH:mm:SS');
   }
   else if (item.RegisterTime) {
    var now = moment(item.RegisterTime);
    return now.format('YYYY-MM-DD HH:mm:SS');
   }
  },
  rowClick: function () {
   window.location = '/account/detail?accountName=' + encodeURIComponent(this.AccountName);
  }
 }
})

效果图:

 


比如表单内容保存,那就更简单了:

j.dispatcher.ajax.company.save({
  validation: {
    rulesCallBack: function (rules) {
      rules.Name.remote = {
        url: '/handler/validation.ashx?type=cn',
        type: "post", //提交方式
        data: {
          CompanyName: function () {
            return encodeURIComponent($("#Name").val()); //编码数据
          }
        }
      }
      rules.ConfirmParssword.equalTo = "#Password";
      rules.AccountName.remote = {
        url: '/handler/validation.ashx?type=an',
        type: "post", //提交方式
        data: {
          AccountName: function () {
            return encodeURIComponent($("#AccountName").val()); //编码数据
          }
        }
      }
    },
    messagesCallBack: function (messages) {
      messages.Name.remote = '该公司已经被注册!';
      messages.AccountName.remote = '该用户名已经存在!';
      messages.ConfirmParssword.equalTo = '两次密码不一致';
    },
    filters: ['Cellphone', 'Email']
  },
  post: {
    success: function () {
      alert(this.message);
      window.location ='/company/list';
    }
  }
});
后端:后端其实很简单类,只要有这样分发器的实现地址就可以了,比如上面的:/company/save

PS: 前端管理框架我是用于基于bootsrap的一个后台框架.

 

有同学问,js什么什么,这个只是自己封装的一个js库,后续会跟大家分享

以上内容就是本文的全部叙述,希望对大家有所帮助。


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3