如何用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 相关文章推荐
jquery自定义属性(类型/属性值)
May 21 Javascript
jquery中get,post和ajax方法的使用小结
Feb 04 Javascript
JavaScript中Date对象的常用方法示例
Oct 24 Javascript
javascript垃圾收集机制的原理分析
Dec 08 Javascript
如何理解jQuery中的ajaxSubmit方法
Mar 13 Javascript
bootstrapvalidator之API学习教程
Jun 29 Javascript
利用babel将es6语法转es5的简单示例
Dec 01 Javascript
JavaScript文本特效实例小结【3个示例】
Dec 22 Javascript
LayUi数据表格自定义赋值方式
Oct 26 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
Mar 17 Javascript
JS实现图片懒加载(lazyload)过程详解
Apr 02 Javascript
linux服务器快速卸载安装node环境(简单上手)
Feb 22 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实现股票趋势图和柱形图
2015/02/07 PHP
隐性调用php程序的方法
2015/06/13 PHP
laravel 自定义常量的两种方案
2019/10/14 PHP
laravel excel 上传文件保存到本地服务器功能
2019/11/14 PHP
最新28个很棒的jQuery 教程
2011/05/28 Javascript
浅析JavaScript中的CSS属性及命名规范
2013/11/28 Javascript
Javascript动画的实现原理浅析
2015/03/02 Javascript
在JavaScript中如何解决用execCommand(
2015/10/19 Javascript
JS实现Fisheye效果动感放大菜单代码
2015/10/21 Javascript
基于javascript代码检测访问网页的浏览器呈现引擎、平台、Windows操作系统、移动设备和游戏系统
2015/12/03 Javascript
AngularJS中监视Scope变量以及外部调用Scope方法
2016/01/23 Javascript
Vue.js表单控件实践
2016/10/27 Javascript
Angularjs中的页面访问权限怎么设置
2016/11/11 Javascript
Bootstrap CSS使用方法
2016/12/23 Javascript
bootstrap multiselect 多选功能实现方法
2017/06/05 Javascript
浅谈angular4 ng-content 中隐藏的内容
2017/08/18 Javascript
微信小程序如何获取用户信息
2018/01/26 Javascript
vue mounted组件的使用
2018/06/18 Javascript
JS字符串常用操作方法实例小结
2019/06/24 Javascript
ant design pro中可控的筛选和排序实例
2020/11/17 Javascript
[05:08]DOTA2-DPC中国联赛3月6日Recap集锦
2021/03/11 DOTA
Python3.x和Python2.x的区别介绍
2013/02/12 Python
深入Python函数编程的一些特性
2015/04/13 Python
简单易懂的python环境安装教程
2017/07/13 Python
Python使用装饰器进行django开发实例代码
2018/02/06 Python
Python爬虫实现获取动态gif格式搞笑图片的方法示例
2018/12/24 Python
Python数据可视化之画图
2019/01/15 Python
总结Python图形用户界面和游戏开发知识点
2019/05/22 Python
python快速排序的实现及运行时间比较
2019/11/22 Python
如何写好升职自荐信
2014/01/06 职场文书
2014年大班元旦活动方案
2014/02/26 职场文书
简单的项目建议书模板
2014/03/12 职场文书
考试作弊被抓检讨书
2014/10/02 职场文书
2015年财政局工作总结
2015/05/21 职场文书
理解深度学习之深度学习简介
2021/04/14 Python
mysql事务隔离级别详情
2021/10/24 MySQL