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


Posted in Javascript onAugust 03, 2015

大家在做些页面的时候,很多都是用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);
  }
 }
})

效果图:

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

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

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什么什么,这个只是自己封装的一个js库,后续会跟大家分享

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

Javascript 相关文章推荐
javascript实现动态侧边栏代码
Feb 19 Javascript
JS中实现简单Formatter函数示例代码
Aug 19 Javascript
一个很有趣3D球状标签云兼容IE8
Aug 22 Javascript
jQuery实现新消息闪烁标题提示的方法
Mar 11 Javascript
基于jQuery实现的无刷新表格分页实例
Feb 17 Javascript
百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
Feb 19 Javascript
js倒计时显示实例
Dec 11 Javascript
js实现随机抽选效果、随机抽选红色球效果
Jan 13 Javascript
浅谈Webpack 持久化缓存实践
Mar 22 Javascript
vue实现div拖拽互换位置
Jul 29 Javascript
详解ES7 Decorator 入门解析
Feb 18 Javascript
js实现mp3录音通过websocket实时传送+简易波形图效果
Jun 12 Javascript
javascript常见数据验证插件大全
Aug 03 #Javascript
javascript自定义in_array()函数实现方法
Aug 03 #Javascript
JavaScript简单修改窗口大小的方法
Aug 03 #Javascript
javascript实现随机读取数组的方法
Aug 03 #Javascript
JS实现选择TextArea内文本的方法
Aug 03 #Javascript
Javascript连接Access数据库完整实例
Aug 03 #Javascript
Javascript使用post方法提交数据实例
Aug 03 #Javascript
You might like
PHP 使用MySQL管理Session的回调函数详解
2013/06/21 PHP
PHP小技巧之函数重载
2014/06/02 PHP
PHP中mysql_field_type()函数用法
2014/11/24 PHP
PHP弱类型的安全问题详细总结
2016/09/25 PHP
php框架CodeIgniter使用redis的方法分析
2018/04/13 PHP
Swoole实现异步投递task任务案例详解
2019/04/02 PHP
Jquery 例外被抛出且未被接住原因介绍
2013/09/04 Javascript
javascript实现点击按钮让DIV层弹性移动的方法
2015/02/24 Javascript
基于jquery实现select选择框内容左右移动添加删除代码分享
2015/08/25 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
js鼠标单击和双击事件冲突问题的快速解决方法
2016/07/11 Javascript
AngularJS基础 ng-options 指令详解
2016/08/02 Javascript
关于 jQuery Easyui异步加载tree的问题解析
2016/12/06 Javascript
@ResponseBody 和 @RequestBody 注解的区别
2017/03/08 Javascript
微信小程序slider组件使用详解
2018/01/31 Javascript
小程序实现列表点赞功能
2018/11/02 Javascript
微信小程序去除左上角返回键的实现方法
2020/03/06 Javascript
微信小程序实现搜索功能
2020/03/10 Javascript
JavaScript cookie原理及使用实例
2020/05/08 Javascript
浅析vue中的nextTick
2020/12/28 Vue.js
[06:07]DOTA2-DPC中国联赛 正赛 Ehome vs VG 选手采访
2021/03/11 DOTA
python实现发送邮件及附件功能
2021/03/02 Python
基于Django与ajax之间的json传输方法
2018/05/29 Python
python实现弹跳小球
2019/05/13 Python
python操作excel让工作自动化
2019/08/09 Python
对Python 字典元素进行删除的方法
2020/07/31 Python
英国皇家造币厂:The Royal Mint
2018/10/05 全球购物
行政助理岗位职责
2013/11/10 职场文书
小学中秋节活动方案
2014/02/06 职场文书
人事部专员岗位职责
2014/03/04 职场文书
篝火晚会主持词
2014/03/25 职场文书
安全环保标语
2014/06/09 职场文书
房产公证书
2015/01/23 职场文书
幼儿园中班个人总结
2015/02/28 职场文书
2019年度行政文员工作计划范本!
2019/07/04 职场文书
微软团队与 NASA 科学家和惠普企业(HPE)的工程师合作
2022/04/21 数码科技