如何用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库,后续会跟大家分享

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

(0)

相关推荐

  • 详解AngularJS中的依赖注入机制

    依赖注入是一个在组件中给出的替代了硬的组件内的编码它们的依赖关系的软件设计模式.这减轻一个组成部分,从定位的依赖,依赖配置.这有助于使组件可重用,维护和测试. AngularJS提供了一个至高无上的依赖注入机制.它提供了一个可注入彼此依赖下列核心组件. 值 工厂 服务 提供者 常值 值 值是简单的JavaScript对象,它是用来将值传递过程中的配置相位控制器. //define a module var mainApp = angular.module("mainApp", []);

  • Javascript技术栈中的四种依赖注入详解

    作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道经久不衰.比如在J2EE中,就有大名鼎鼎的执牛耳者Spring.Javascript社区中自然也不乏一些积极的尝试,广为人知的AngularJS很大程度上就是基于DI实现的.遗憾的是,作为一款缺少反射机制.不支持Annotation语法的动态语言,Javascript长期以来都没有属于自己的Spri

  • 浅析依赖注入框架Autofac的使用

    下面通过代码给大家分享下依赖注入框架Autofac的使用,具体如下所示:  Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上也是很高的. 1)解压它的压缩包,主要看到Autofac.dll,Autofac.Configuration.dll,这也是本篇文章重点使用的Autofac的类库. 2)创建一个控制台工程,并且引用以上的DLL文件.创建一个数据库操作接口IDatabase.cs: /// <summary

  • Laravel实现构造函数自动依赖注入的方法

    本文实例讲述了Laravel实现构造函数自动依赖注入的方法.分享给大家供大家参考,具体如下: 在Laravel的构造函数中可以实现自动依赖注入,而不需要实例化之前先实例化需要的类,如代码所示: <?php namespace Lio\Http\Controllers\Forum; use Lio\Forum\Replies\ReplyRepository; use Lio\Forum\Threads\ThreadCreator; use Lio\Forum\Threads\ThreadCreat

  • 详解Java Spring各种依赖注入注解的区别

    注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Component. Autowired是自动注入,自动从spring的上下文找到合适的bean来注入 Resource用来指定名称注入 Qualifier和Autowired配合使用,指定bean的名称 Service,Controller,Repository分别标记类是Service层类,Contro

  • AngularJs动态加载模块和依赖注入详解

    废话不多说,进入正题... 首先我们看下文件结构: Angular-ocLazyLoad --- demo文件夹 Scripts --- 框架及插件文件夹 angular-1.4.7 --- angular 不解释 angular-ui-router --- uirouter 不解释 oclazyload --- ocLazyload 不解释 bootstrap --- bootstrap 不解释 angular-tree-control-master --- angular-tree-cont

  • 深入解析Java的Spring框架中bean的依赖注入

    每一个基于java的应用程序都有一个共同工作来展示给用户看到的内容作为工作的应用几个对象.当编写一个复杂的Java应用程序,应用程序类应该尽可能独立其他Java类来增加重复使用这些类,并独立于其他类别的测试它们,而这样做单元测试的可能性.依赖注入(或有时称为布线)有助于粘合这些类在一起,同时保持他们的独立. 考虑有其中有一个文本编辑器组件的应用程序,要提供拼写检查.标准的代码将看起来像这样: public class TextEditor { private SpellChecker spell

  • 深入理解Javascript里的依赖注入

    迟早你需要用到其他开发人员的抽象成果--即你依靠别人的代码.我喜欢依赖自由(无依赖)的模块,但那是难以实现的.甚至你创建的那些漂亮的黑盒子组件也或多或少会依赖一些东西.这正是依赖注入大显身手的之处.现在有效地管理依赖的能力是绝对必要的.本文总结了我对问题探索和一些的解决方案. 一.目标设想我们有两个模块.第一个是负责Ajax请求服务(service),第二个是路由(router). 复制代码 代码如下: var service = function() {    return { name: '

  • 扩展ASP.NET MVC三层框架且使用StructureMap实现依赖注入1-Model层

    本篇文章将向大家介绍如何添加Service和Repository层并且使用StructureMap把Service层注入到Controller,把Repository注入到Service层.Service层主要是我们的业务逻辑层,这一层不和底层的Database打交道,和Database打交道的是Repository数据持久层.本篇文章通过使用StructureMap依赖注入使Controller,Service,Repository三层的耦合度降到最低. 本系统使用NorthWind开源数据,

  • 面向对象编程依赖注入详解

    说说依赖注入 在面向对象编程中,我们经常处理处理的问题就是解耦,程序的耦合性越低表明这个程序的可读性以及可维护性越高.控制反转(Inversion of Control或IoC)就是常用的面向对象编程的设计原则,使用这个原则我们可以降低耦合性.其中依赖注入是控制反转最常用的实现. 什么是依赖 依赖是程序中常见的现象,比如类Car中用到了GasEnergy类的实例energy,通常的做法就是在Car类中显式地创建GasEnergy类的实例,并赋值给energy.如下面的代码 interface E

随机推荐