如何用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)正確填寫您的手機(jī)號(hào)碼");
jQuery.validator.addMethod("isEamil", function (value, element) {
return j.config.reg_email.test(value);
}, "請(qǐng)?zhí)顚懻_的郵箱地址");
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)可拖拽的拖動(dòng)層Div實(shí)例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)可拖拽的拖動(dòng)層Div的方法,拖拽頁(yè)面中的div塊可實(shí)現(xiàn)div塊按照拖動(dòng)軌跡移動(dòng)的效果,涉及javascript鼠標(biāo)事件、頁(yè)面元素樣式結(jié)合事件函數(shù)動(dòng)態(tài)操作的相關(guān)技巧,需要的朋友可以參考下2015-08-08
js實(shí)現(xiàn)用戶離開(kāi)頁(yè)面前提示是否離開(kāi)此頁(yè)面的方法(包括瀏覽器按鈕事件)
這篇文章主要介紹了js實(shí)現(xiàn)用戶離開(kāi)頁(yè)面前提示是否離開(kāi)此頁(yè)面的方法,較為詳細(xì)的分析了javascript針對(duì)瀏覽器事件的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
JavaScript中Textarea滾動(dòng)條不能拖動(dòng)的解決方法
這篇文章主要介紹了JavaScript中Textarea滾動(dòng)條不能拖動(dòng)的解決方法,主要針對(duì)IE瀏覽器中Textarea滾動(dòng)條綁定了onfocus事件時(shí)分析對(duì)應(yīng)的處理方法,需要的朋友可以參考下2015-12-12
JS實(shí)現(xiàn)針對(duì)給定時(shí)間的倒計(jì)時(shí)功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)針對(duì)給定時(shí)間的倒計(jì)時(shí)功能,結(jié)合具體實(shí)例形式分析了javascript日期時(shí)間的正則判定與動(dòng)態(tài)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-04-04
javascript 使用 NodeList需要注意的問(wèn)題
理解NodeList及其近親NamedNodeMap和HTMLCollection,是從整體上透徹理解DOM的關(guān)鍵所在,這三個(gè)集合都是“動(dòng)態(tài)的”,換句話說(shuō),每當(dāng)文檔結(jié)構(gòu)發(fā)生變化時(shí),他們都會(huì)得到更新。2013-03-03
js 毫秒轉(zhuǎn)天時(shí)分秒的實(shí)例
下面小編就為大家分享一篇js 毫秒轉(zhuǎn)天時(shí)分秒的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-11-11

