如何用js 實(shí)現(xiàn)依賴注入的思想,后端框架思想搬到前端來(lái)
大家在做些頁(yè)面的時(shí)候,很多都是用ajax實(shí)現(xiàn)的,在顯示的時(shí)候有很多表單提交的add或者update操作,顯然這樣很煩,突然想到了一個(gè)比較好的方法,下面給大家分享下如何用js 實(shí)現(xiàn)依賴注入的思想,后端框架思想搬到前端來(lái)。
應(yīng)用場(chǎng)景: 前后端一一對(duì)應(yīng)、表單內(nèi)容保存、列表陳述等。
架構(gòu)思路: 分發(fā)器、依賴注入等。
基本代碼陳述:
j.extend({ dispatcher: (function () { var _route = {}, // default module _module = { // 授權(quán) authenticate: true, // 驗(yàn)證 validation: true, // 數(shù)據(jù)轉(zhuǎn)換 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); }, "請(qǐng)輸入6-20密碼建議由數(shù)字、字母和符號(hào)組成!"); jQuery.validator.addMethod("isMobile", function (value, element) { return j.config.reg_phone.test(value); }, "請(qǐng)正確填寫(xiě)您的手機(jī)號(hào)碼"); jQuery.validator.addMethod("isEamil", function (value, element) { return j.config.reg_email.test(value); }, "請(qǐng)?zhí)顚?xiě)正確的郵箱地址"); jQuery.validator.addMethod("isUserName", function (value, element) { return j.config.reg_login_name.test(value); }, "4-32位字符.支持漢字、字母、數(shù)字\"-\"\"_\"組合"); } 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: ['編號(hào)', '用戶名', '賬戶類型', '公司類型', '注冊(cè)時(shí)間', '最后登錄時(shí)間', '是否啟用', '操作'], 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); } } })
效果圖:
比如表單內(nèi)容保存,那就更簡(jiǎn)單了:
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()); //編碼數(shù)據(jù)
}
}
}
rules.ConfirmParssword.equalTo = "#Password";
rules.AccountName.remote = {
url: '/handler/validation.ashx?type=an',
type: "post", //提交方式
data: {
AccountName: function () {
return encodeURIComponent($("#AccountName").val()); //編碼數(shù)據(jù)
}
}
}
},
messagesCallBack: function (messages) {
messages.Name.remote = '該公司已經(jīng)被注冊(cè)!';
messages.AccountName.remote = '該用戶名已經(jīng)存在!';
messages.ConfirmParssword.equalTo = '兩次密碼不一致';
},
filters: ['Cellphone', 'Email']
},
post: {
success: function () {
alert(this.message);
window.location ='/company/list';
}
}
});
后端:后端其實(shí)很簡(jiǎn)單類,只要有這樣分發(fā)器的實(shí)現(xiàn)地址就可以了,比如上面的:/company/save
PS: 前端管理框架我是用于基于bootsrap的一個(gè)后臺(tái)框架.
有同學(xué)問(wèn),js什么什么,這個(gè)只是自己封裝的一個(gè)js庫(kù),后續(xù)會(huì)跟大家分享
以上內(nèi)容就是本文的全部敘述,希望對(duì)大家有所幫助。
- AngularJs動(dòng)態(tài)加載模塊和依賴注入詳解
- 深入理解Javascript里的依賴注入
- 詳解AngularJS中的依賴注入機(jī)制
- 淺析依賴注入框架Autofac的使用
- 詳解Java Spring各種依賴注入注解的區(qū)別
- 擴(kuò)展ASP.NET MVC三層框架且使用StructureMap實(shí)現(xiàn)依賴注入1-Model層
- Laravel實(shí)現(xiàn)構(gòu)造函數(shù)自動(dòng)依賴注入的方法
- Javascript技術(shù)棧中的四種依賴注入詳解
- 深入解析Java的Spring框架中bean的依賴注入
- 面向?qū)ο缶幊桃蕾囎⑷朐斀?/a>
相關(guān)文章
JavaScript實(shí)現(xiàn)二分查找實(shí)例代碼
二分查找的前提為:數(shù)組、有序。這篇文章主要介紹了JavaScript實(shí)現(xiàn)二分查找實(shí)例代碼,需要的朋友可以參考下2017-02-02詳談構(gòu)造函數(shù)加括號(hào)與不加括號(hào)的區(qū)別
下面小編就為大家?guī)?lái)一篇詳談構(gòu)造函數(shù)加括號(hào)與不加括號(hào)的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10前端終止請(qǐng)求的3種方式總結(jié)(ajax、axios)
這篇文章主要給大家總結(jié)介紹了關(guān)于前端終止請(qǐng)求的3種方式,其中包括ajax、axios的相關(guān)資料, 取消請(qǐng)求在前端有時(shí)候會(huì)用到,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09微信小程序?qū)崿F(xiàn)單個(gè)卡片左滑顯示按鈕并防止上下滑動(dòng)干擾功能
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)單個(gè)卡片左滑顯示按鈕并防止上下滑動(dòng)干擾功能,利用小程序事件處理的api,分別讀取觸摸開(kāi)始,觸摸移動(dòng)時(shí),觸摸結(jié)束的X/Y坐標(biāo),根據(jù)差值來(lái)改變整個(gè)卡片的位置,具體實(shí)例代碼跟隨小編一起看看吧2019-12-12javascript下對(duì)于事件、事件流、事件觸發(fā)的順序隨便說(shuō)說(shuō)
向同一個(gè)標(biāo)簽 動(dòng)態(tài)的添加事件是 執(zhí)行的順序在ie和其他非ie內(nèi)核的瀏覽器有所不同 ie是“先進(jìn)先出 ” 就是最先添加的最先執(zhí)行,其他非ie內(nèi)核的瀏覽器是 “先進(jìn)后出”,就是 最后添加的事件 先執(zhí)行。2010-07-07js實(shí)現(xiàn)二代身份證號(hào)碼驗(yàn)證詳解
本文給大家分享一段超級(jí)全面的二代身份證號(hào)碼驗(yàn)證程序,由JS編寫(xiě)而成,可以校驗(yàn)身份證的地址碼、出生日期碼、順序碼和數(shù)字校驗(yàn)碼。是身份證去偽存真的一大利器。2014-11-11微信小程序獲取位置展示地圖并標(biāo)注信息的實(shí)例代碼
這篇文章主要介紹了微信小程序獲取位置展示地圖并標(biāo)注信息的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09uni?app跨端自定義指令實(shí)現(xiàn)按鈕權(quán)限
這篇文章主要為大家介紹了uni?app跨端自定義指令實(shí)現(xiàn)按鈕權(quán)限詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12JavaScript監(jiān)聽(tīng)一個(gè)DOM元素大小變化
這篇文章主要介紹了JavaScript監(jiān)聽(tīng)一個(gè)DOM元素大小變化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04