1、需求背景
很多时候,我们使用jquery.ajax的方式向后台发送请求,型如
$.ajax({ ???type: "post", ???url: "/User/Edit", ???data: { data: JSON.stringify(postdata) }, ???success: function (data, status) { ???????if (status == "success") { ???????????toastr.success(‘提交数据成功‘); ???????????$("#tb_aaa").bootstrapTable(‘refresh‘); ???????} ???}, ???error: function (e) { ???}, ???complete: function () { ???}});
这种代码太常见了,这个时候我们有这样一个需求:在自己调用ajax请求的时候,我们不想每次都写error:function(e){}这种代码,但是我们又想让它每次都将ajax的错误信息输出到浏览器让用户能够看到。怎么办呢?
2、实现原理
要想实现以上效果其实并不难,我们可以将$.ajax({})封装一层,在封装的公共方法里面定义error对应的事件即可。确实,这样能达到我们的要求,但是并不完美,原因很简单:1)在jquery的基础上面再封装一层,效率不够高;2)需要改变调用者的习惯,每次调用ajax的时候需要按照我们定义的方法的规则来写,而不能直接用原生的$.ajax({})这种写法,这是我们不太想看到。
既然如此,那我们如何做到既不封装控件,又能达到以上要求呢?答案就是通过我们的$.extend去扩展原生的jquery.ajax。
其实实现起来也并不难,通过以下一段代码就能达到我们的要求。
(function ($) { ???//1.得到$.ajax的对象 ???var _ajax = $.ajax; ???$.ajax = function (options) { ???????//2.每次调用发送ajax请求的时候定义默认的error处理方法 ???????var fn = { ???????????error: function (XMLHttpRequest, textStatus, errorThrown) { ???????????????toastr.error(XMLHttpRequest.responseText, ‘错误消息‘, { closeButton: true, timeOut: 0, positionClass: ‘toast-top-full-width‘ }); ???????????}, ???????????success: function (data, textStatus) { }, ???????????beforeSend: function (XHR) { }, ???????????complete: function (XHR, TS) { } ???????} ???????//3.如果在调用的时候写了error的处理方法,就不用默认的 ???????if (options.error) { ???????????fn.error = options.error; ???????} ???????if (options.success) { ???????????fn.success = options.success; ???????} ???????if (options.beforeSend) { ???????????fn.beforeSend = options.beforeSend; ???????} ???????if (options.complete) { ???????????fn.complete = options.complete; ???????} ???????//4.扩展原生的$.ajax方法,返回最新的参数 ???????var _options = $.extend(options, { ???????????error: function (XMLHttpRequest, textStatus, errorThrown) { ???????????????fn.error(XMLHttpRequest, textStatus, errorThrown); ???????????}, ???????????success: function (data, textStatus) { ???????????????fn.success(data, textStatus); ???????????}, ???????????beforeSend: function (XHR) { ???????????????fn.beforeSend(XHR); ???????????}, ???????????complete: function (XHR, TS) { ???????????????fn.complete(XHR, TS); ???????????} ???????}); ???????//5.将最新的参数传回ajax对象 ???????_ajax(_options); ???};})(jQuery);
如果没接触过jquery里面$.extend这个方法的童鞋可能看不懂以上是什么意思?那么请看之前我写的博客,介绍比较详细:jQuery.extend() 函数使用详解
了解了$.extend()的作用,我们就能大概看懂上面那个扩展jquery.ajax的实现了吧。主要的步骤分为:
1)定义默认的error处理方法。
2)判断用户在调用$.ajax({})的时候是否自定了error:function(){},如果定义过,则使用用户定义的,反之则用默认的error处理方法。
3)使用$.extend()将error默认处理方法传入$.ajax()的参数中。我们看options参数时包含$.ajax()方法里面所有的参数的,然后用默认的fn去扩展它即可。
通过以上三步就能够实现对$.ajax()方法里面error默认处理方法。这样扩展,对于我们使用者来说完全感觉不到变化,我们仍然可以$.ajax({});这样去发送ajax请求,如果没有特殊情况,不用写error处理方法。
组件扩展的意义:使用组件扩展,能够帮助我们在原有组件上面增加一些和我们系统业务相关的处理需求,而在使用时,还是和使用原生组件一样去调用,免去了在组件上面再封装一层的臃肿。
3、实例:
function btn_delete() { ???var keyValue = $("#gridTable").jqGridRowValue("id"); ???if (checkedArray(keyValue)) { ???????$.RemoveForm({ ???????????msg:"该设备删除之后,无法进行管控,也无法进行卸载,您确定要继续删除吗?",//这些内容均用于自定义 ???????????url: "${basePath}/assets/deviceAction_delete.do", ???????????param: {"ids": keyValue }, ???????????success: function (responseText) { ???????????????if (responseText == "success") { ????????????????????dialogMsg("<s:text name="cems.public.msgSuccess"></s:text>", 1); ???????????????} else if(responseText !="" && responseText !="error"){ ???????????????????dialogAlert("<s:text name="cems.public.msgFail"></s:text>", -1); ???????????????} else { ???????????????????dialogAlert("<s:text name="cems.public.msgFail"></s:text>", -1); ???????????????} ???????????????$("#gridTable").trigger("reloadGrid"); ???????????} ???????}) ???} else { ???????dialogMsg(‘请选择需要删除的用户!‘, 0); ???}}
封装的方法:
$.RemoveForm = function (options) { ???var defaults = { ???????msg: "注:您确定要删除吗?该操作将无法恢复", ???????loading: "正在删除数据...", ???????url: "", ???????param: [], ???????type: "post", ???????dataType: "text", ???????success: null ???}; ???var options = $.extend(defaults, options); ???dialogConfirm(options.msg, function (r) { ???????if (r) { ???????????Loading(true, options.loading); ???????????window.setTimeout(function () { ???????????????var postdata = options.param; ???????????????if ($(‘[name=__RequestVerificationToken]‘).length > 0) { ???????????????????postdata["__RequestVerificationToken"] = $(‘[name=__RequestVerificationToken]‘).val(); ???????????????} ???????????????$.ajax({ ???????????????????url: options.url, ???????????????????data: postdata, ???????????????????type: options.type, ???????????????????dataType: options.dataType, ???????????????????success: function (data) { ????????????????????????options.success(data); ???????????????????????/*if (data.type == "3") { ???????????????????????????dialogAlert(data.message, -1); ???????????????????????} else { ???????????????????????????dialogMsg(data.message, 1); ???????????????????????????options.success(data); ???????????????????????}*/ ???????????????????}, ???????????????????error: function (XMLHttpRequest, textStatus, errorThrown) { ???????????????????????Loading(false); ???????????????????????dialogMsg(errorThrown, -1); ???????????????????}, ???????????????????beforeSend: function () { ???????????????????????Loading(true, options.loading); ???????????????????}, ???????????????????complete: function () { ???????????????????????Loading(false); ???????????????????} ???????????????}); ???????????}, 500); ???????} ???});}
JS组件系列——封装自己的JS组件
原文地址:http://www.cnblogs.com/goloving/p/7660374.html