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

前述:咱们写一些页面的时候,很多需要用ajax来实现,显示又有很多表单提交的add或者update操作,太烦了,能不能有什么方法能够简单些呢? 说实话我都是被公司给逼的

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

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

基本代码陈述:

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的一个后台框架,可以看学徒帮演示的页面:http://www.xuetub.com/plugin/jquery/278

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

交流: 太忙了,以代码陈述为主,很多细节并没有优化,大侠们可以自己优化啦,如有小白、小黑、小黄同学,可以关注学徒帮,www.xuetub.com,关注jQuery插件,查看演示,扫二维码关注我啦。

时间: 2024-10-26 14:46:20

js 实现依赖注入的思想,后端框架思想搬到前端来的相关文章

angular.js的依赖注入解析

本教程使用AngularJS版本:1.5.3        angularjs GitHub: https://github.com/angular/angular.js/        AngularJs下载地址:https://angularjs.org/ 用有过spring的人都知道,Spring的核心思想就是DI(依赖注入,Dependency Injection)和IOC(控制反转 Invension of Controller),AngularJS的service其实就是用到了这里的

Angular JS的依赖注入

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

简单实现依赖注入(无框架)

1.依赖注入概念 在Spring框架中,依赖注入(IOC)和面向切面编程(AOP)是它的两大核心.其中依赖注入是一个将行为从依赖中分离的技术,简单地说,它允许开发者定义一个方法函数依赖于外部其他各种交互,而不需要编码如何获得这些外部交互的实例. 这样就在各种组件之间解耦,从而获得干净的代码,相比依赖的硬编码, 一个组件只有在运行时才调用其所需要的其他组件,因此在代码运行时,通过特定的框架或容器,将其所需要的其他依赖组件进行注入,主动注入. 2.依赖注入实现       依赖注入的实现是基于反射实

[转]第二章 控制反转和依赖注入

Spring.Net 中提供了很多功能,比如依赖注入,面向切面编程(AOP),数据访问抽象以及ASP.Net扩展等等的功能.而其中最核心的功能就是依赖注入(Dependency Injection),而使用依赖注入带来的最大好处就是能够通过它降低应用程序中对象与对象之间的耦合. 控制反转(Inversion of Control)和 依赖注入(Dependency Injection),他们的英文缩写分别是IOC和DI,其实它们是同一个概念的不同角度的描述,由于控制反转概念比较模糊(可能只是理解

深入理解ASP.NET 5的依赖注入

(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:ASP.NET 5整个底层都架构于依赖注入机制之下,今天介绍的文章详细介绍了内置依赖注入容器. 在ASP.NET之前的版本中,虽然各个框架(MVC.WEB API.SignalR)都支持依赖注入,但是由于框架是相互独立的,所以使用依赖注入的方式都有所差异.Katana曾经期望通过OWIN来统一这些差异,直到ASP.NET 5中才得以实现.这得利于整个ASP.NET 5都是构建于依赖注入机制之下

ABP依赖注入

ABP依赖注入 点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之6.ABP依赖注入 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开源项目:https://github.com/aspnetboilerplate 本文由 上海-半冷 提供翻译 什么是依赖注入 如果你已经知道依赖注入的概念,构造函

基于DDD的现代ASP.NET开发框架--ABP系列之6、ABP依赖注入

点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之6.ABP依赖注入 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开源项目:https://github.com/aspnetboilerplate 本文由 上海-半冷 提供翻译 什么是依赖注入 如果你已经知道依赖注入的概念,构造函数和属性注入模式

依赖、依赖倒置、控制反转、依赖注入

1.依赖 依赖就是有联系,有地方使用到它就是有依赖它,一个系统不可能完全避免依赖.如果你的一个类或者模块在项目中没有用到它,恭喜你,可以从项目中剔除它或者排除它了,因为没有一个地方会依赖它.下面看一个简单的示例: /// <summary> /// 用户播放媒体文件 /// </summary> public class OperationMain { public void PlayMedia() { MediaFile _mtype = new MediaFile(); Pla

JavaScript依赖注入的实现思路

JavaScript依赖注入的实现思路 如今各个框架都在模块化,连前端的javascript也不例外.每个模块负责一定的功能,模块与模块之间又有相互依赖,那么问题来了:javascript的依赖注入如何实现?(javascript的依赖注入,各大框架都有相应的实现,这里只学习实现思路) 如下需求: 假设已经有定义好的服务模块Key-Value集合,func为添加的新服务,参数列表为服务依赖项. var services = { abc : 123, def : 456, ghi : 789 };