如何用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写动态树示例代码
Jul 31 Javascript
JS中call/apply、arguments、undefined/null方法详解
Feb 15 Javascript
jQuery获取与设置iframe高度的方法
Aug 01 Javascript
详解Vue2.0里过滤器容易踩到的坑
Jun 01 Javascript
Angular.js初始化之ng-app的自动绑定与手动绑定详解
Jul 31 Javascript
js推箱子小游戏步骤代码解析
Jan 10 Javascript
vue-lazyload图片延迟加载插件的实例讲解
Feb 09 Javascript
详解离线安装npm包的几种方法
Nov 25 Javascript
在 Vue 应用中使用 Netlify 表单功能的方法详解
Jun 03 Javascript
微信小程序左滑删除实现代码实例
Sep 16 Javascript
jQuery实现轮播图效果demo
Jan 11 jQuery
微信小程序返回上一级页面的实现代码
Jun 19 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
Flash空降上海 化身大魔王接受挑战
2020/03/02 星际争霸
简单的方法让你的后台登录更加安全(php中加session验证)
2012/08/22 PHP
Mysql中分页查询的两个解决方法比较
2013/05/02 PHP
fetchAll()与mysql_fetch_array()的区别详解
2013/06/05 PHP
PHP的swoole扩展安装方法详细教程
2016/05/18 PHP
php使用get_class_methods()函数获取分类的方法
2016/07/20 PHP
详解phpstorm2020最新破解方法
2020/09/17 PHP
从javascript语言本身谈项目实战
2006/12/27 Javascript
javascript解决innerText浏览器兼容问题思路代码
2013/05/17 Javascript
基于jquery实现的省市区级联无ajax
2013/09/24 Javascript
动态添加删除表格行的js实现代码
2014/02/28 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
2015/01/19 Javascript
webpack项目调试以及独立打包配置文件的方法
2018/02/28 Javascript
jQuery实现为table表格动态添加或删除tr功能示例
2019/02/19 jQuery
laravel实现中文和英语互相切换的例子
2019/09/30 Javascript
vue计算属性无法监听到数组内部变化的解决方案
2019/11/06 Javascript
react-native 实现购物车滑动删除效果的示例代码
2021/01/15 Javascript
[46:27]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#2LGD VS MVP.Phx第一局
2016/03/02 DOTA
[01:02:55]CHAOS vs Mineski 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
python机器人行走步数问题的解决
2018/01/29 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
2019/12/13 Python
pycharm 中mark directory as exclude的用法详解
2020/02/14 Python
python实现微信打飞机游戏
2020/03/24 Python
Python接口开发实现步骤详解
2020/04/26 Python
解决Pymongo insert时会自动添加_id的问题
2020/12/05 Python
法国珠宝店:CLEOR
2017/01/29 全球购物
佛罗里达州印第安河新鲜水果:Hale Groves
2017/02/20 全球购物
美国婴儿用品及配件购买网站:Munchkin
2019/04/03 全球购物
英语自荐信常用语句
2013/12/13 职场文书
11月升旗仪式讲话稿
2014/02/15 职场文书
大专生求职信
2014/06/29 职场文书
学校法制宣传日活动总结
2014/11/01 职场文书
工作检讨书大全
2015/01/26 职场文书
学生病假条范文
2015/08/17 职场文书
2016年端午节校园广播稿
2015/12/18 职场文书
Java数组详细介绍及相关工具类
2022/04/14 Java/Android