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去扩展它即可。($.extend()方法拓展参数列表

  通过以上三步就能够实现对$.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);}});
}

  实例2:以select这个组件为例,很多情况下,我们的select里面的option都是需要从数据库里面取数据的,所以一般的做法就是发送一个ajax请求,然后在success方法里面拼html。现在我们就封装一个select远程取数据的方法。

(function ($) {//1.定义jquery的扩展方法combobox$.fn.combobox = function (options, param) {if (typeof options == 'string') {return $.fn.combobox.methods[options](this, param);}//2.将调用时候传过来的参数和default参数合并options = $.extend({}, $.fn.combobox.defaults, options || {});//3.添加默认值var target = $(this);target.attr('valuefield', options.valueField);target.attr('textfield', options.textField);target.empty();var option = $('<option></option>');option.attr('value', '');option.text(options.placeholder);target.append(option);//4.判断用户传过来的参数列表里面是否包含数据data数据集,如果包含,不用发ajax从后台取,否则否送ajax从后台取数据if (options.data) {init(target, options.data);}else {//var param = {};
            options.onBeforeLoad.call(target, options.param);if (!options.url) return;$.getJSON(options.url, options.param, function (data) {init(target, data);});}function init(target, data) {$.each(data, function (i, item) {var option = $('<option></option>');option.attr('value', item[options.valueField]);option.text(item[options.textField]);target.append(option);});options.onLoadSuccess.call(target);}target.unbind("change");target.on("change", function (e) {if (options.onChange)return options.onChange(target.val());});}//5.如果传过来的是字符串,代表调用方法。$.fn.combobox.methods = {getValue: function (jq) {return jq.val();},setValue: function (jq, param) {jq.val(param);},load: function (jq, url) {$.getJSON(url, function (data) {jq.empty();var option = $('<option></option>');option.attr('value', '');option.text('请选择');jq.append(option);$.each(data, function (i, item) {var option = $('<option></option>');option.attr('value', item[jq.attr('valuefield')]);option.text(item[jq.attr('textfield')]);jq.append(option);});});}};//6.默认参数列表$.fn.combobox.defaults = {url: null,param: null,data: null,valueField: 'value',textField: 'text',placeholder: '请选择',onBeforeLoad: function (param) { },onLoadSuccess: function () { },onChange: function (value) { }};
})(jQuery);

  先来看看我们自定义组件如何使用:

  用法一:通过URL远程取数据并初始化

  首先定义一个空的select

<select id="sel_search_plant" class="form-control"></select>

  然后初始化它

$(function(){$('#sel_search_plant').combobox({url: '/apiaction/Plant/Find',valueField: 'TM_PLANT_ID',textField: 'NAME_C'});
})

  用法二:取值和设置

var strSelectedValue = $('#sel_search_plant').combobox("getValue");$('#sel_search_plant').combobox("setValue", "aaa");

  封装思路:

(1)首先看看我们最常看到的如下写法:

(function ($) {//....封装组件逻辑
})(jQuery);

(2)定义自己的组件的代码:习惯这种写法的应该知道,这个就表示向jquery对象添加自定义方法

$.fn.combobox = function (options, param) {};

(3)合并默认参数和用户传进来的参数

options = $.extend({}, $.fn.combobox.defaults, options || {});

(4)默认参数列表:如果用户没有传参,就用默认的参数列表。

$.fn.combobox.defaults = {url: null,param: null,data: null,valueField: 'value',textField: 'text',placeholder: '请选择',onBeforeLoad: function (param) { },onLoadSuccess: function () { },onChange: function (value) { }};

转载于:https://www.cnblogs.com/goloving/p/7660374.html

JS组件系列——封装自己的JS组件相关推荐

  1. JS组件系列——封装自己的JS组件,你也可以

    前言:之前分享了那么多bootstrap组件的使用经验,这篇博主打算研究下JS组件的扩展和封装,我们来感受下JQuery为我们提供$.Extend的神奇,看看我们怎么自定义自己的组件,比如我们想扩展一 ...

  2. bootstrapr表格父子框_JS组件系列之Bootstrap table表格组件神器【二、父子表和行列调序】...

    Bootstrap Table是轻量级的和功能丰富的以表格的形式显示的数据,支持单选,复选框,排序,分页,显示/隐藏列,固定标题滚动表,响应式设计,Ajax加载JSON数据,点击排序的列,卡片视图等. ...

  3. 视频教程-零基础JS入门系列课程(2)之JS语法基础精讲-JavaScript

    零基础JS入门系列课程(2)之JS语法基础精讲 螺钉课堂讲师,擅长Vue.React.ReactNative.NodeJS等前端框架及技术 邓老师 ¥59.00 立即订阅 扫码下载「CSDN程序员学院 ...

  4. JS组件系列——两种bootstrap multiselect组件大比拼

    前言:今天继续来看看bootstrap的另一个组件:multiselect.记得在项目开始之前,博主项目组几个同事就使用哪些js组件展开过讨论,其中就说到了select组件,由于项目的整体风格使用的b ...

  5. C#组件系列——又一款日志组件:Elmah的学习和分享

    前言:好久没动笔了,都有点生疏,12月都要接近尾声,可是这月连一篇的产出都没有,不能坏了"规矩",今天还是来写一篇.最近个把月确实很忙,不过每天早上还是会抽空来园子里逛逛.一如既往 ...

  6. Vant组件库封装可翻页日历组件

    前言 我们在进行VUE开发的时候有的时候会使用到VantUI组件库: https://vant-contrib.gitee.io/vant/v2/#/zh-CN/home#jie-shao Vant ...

  7. java项目中可以封装的组件_封装属于自己的组件库

    封装属于自己的组件库 - VUE 「适合人群:一起聊聊组件这件事」 「观看时间:30min」 「说明:一些经验分享,欢迎探讨」 前言 现目前,vue 社区下大大小小的组件库是越来越多,优秀的开源组件也 ...

  8. 走近Flex组件系列(三):按扭组件(Button,CheckBox,LinkBar,LinkButton,PopUpButton,RadioButton,ToggleButtonBar)...

    本文主要介绍Flex的Button.ButtonBar.CheckBox.LinkBar.LinkButton.PopUpButton.RadioButton.RadioButtonGroup和Tog ...

  9. 转载:Node.js入门系列——《深入浅出Node.js》

    作者:田永强 日期:2011-12-02 完整版 前言: Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS ...

最新文章

  1. visual webgui theme designer
  2. mysql查询_MySQL基础,查询语句详解
  3. 残缺棋盘的伪代码_伪激光雷达:无人驾驶的立体视觉
  4. jQuery.validate.js API
  5. 牛客网 最短路 Floyd算法 Dijkstra算法 Java大数
  6. 【iOS】The run destination iPhone is not valid for Running the scheme .
  7. jQuery文档处理
  8. ModelSim 2019安装教程
  9. 《CSS权威指南》第3版
  10. docucentre s2011默认登录密码
  11. 什么软件画er图方便_如何画好ER图
  12. 串口传输文件练习与点阵汉字的字模读取与显示
  13. 网页内容变化实时监控提醒(多个复杂的监控条件)
  14. windows源文件名称大于文件系统支持的长度无法删除问题
  15. 苹果内购那些事儿(二)
  16. 【数智化案例展】某人民医院——智慧医疗大数据建设
  17. STM32学习之温湿度检测——DHT11
  18. 第28集丨马斯洛的“需求层次论”在讲什么?
  19. 2017-4-15,16
  20. 他们为什么离开微软? 创业热情驱动

热门文章

  1. 图像分类最新技术综述论文: 21种半监督、自监督和无监督学习方法一较高低
  2. 收藏!博士大佬的《机器学习》西瓜书手推笔记!
  3. 一文理解图像处理之HOG特征
  4. GitHub使用指南——如何删除存储库
  5. 盲审不到4分的论文竟中了ICLR 2019??!!ICLR 2019官方这样回应
  6. C语言不挂科之我爱谭浩强——选择填空拿满分(附例题答案和知识点详解)
  7. CNCC2017中的深度学习与跨媒体智能
  8. NMS_非极大值抑制(转)
  9. vue 后台数据列表获取图片_vue使用ajax获取后台数据进行显示的示例
  10. 系统500报警 php_Zabbix3.4 部署、监测及邮件报警