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插件,查看演示,扫二维码关注我啦。

 

posted @ 2015-08-02 18:20  欧西  阅读(1757)  评论(0编辑  收藏  举报