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

前言:之前分享了那么多bootstrap组件的使用经验,这篇博主打算研究下JS组件的扩展和封装,我们来感受下JQuery为我们提供$.Extend的神奇,看看我们怎么自定义自己的组件,比如我们想扩展一个$("#id").MyJsControl({})做我们自己的组件,我们该如何去做呢,别急,我们慢慢来看看过程。

一、扩展已经存在的组件

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 API对$.extend()方法是作何解释的。

什么意思呢?我们来看官方的两个例子就知道了

栗子一:

var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
$.extend(settings, options);

结果:

settings == { validate: true, limit: 5, name: "bar" }

栗子二:

var empty = {};
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
var settings = $.extend(empty, defaults, options);

结果:

settings == { validate: true, limit: 5, name: "bar" }
empty == { validate: true, limit: 5, name: "bar" }

以上的两个简单例子就说明extend()方法作用就是合并另个对象,有相同的则覆盖,没有相同的则添加。就是这么简单。

了解了$.extend()的作用,我们就能大概看懂上面那个扩展jquery.ajax的实现了吧。主要的步骤分为:

1)定义默认的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) { }}

2)判断用户在调用$.ajax({})的时候是否自定了error:function(){},如果定义过,则使用用户定义的,反之则用默认的error处理方法。

3)使用$.extend()将error默认处理方法传入$.ajax()的参数中。我们看options参数时包含$.ajax()方法里面所有的参数的,然后用默认的fn去扩展它即可。

通过以上三步就能够实现对$.ajax()方法里面error默认处理方法。这样扩展,对于我们使用者来说完全感觉不到变化,我们仍然可以$.ajax({});这样去发送ajax请求,如果没有特殊情况,不用写error处理方法。

3、组件扩展的意义

使用组件扩展,能够帮助我们在原有组件上面增加一些和我们系统业务相关的处理需求,而在使用时,还是和使用原生组件一样去调用,免去了在组件上面再封装一层的臃肿。

二、扩展自己组件

上面通过$.extend()方法扩展了$.ajax()的error事件处理方法。下面我们来封装一个自己的组件试试,功能很简单,但比较有说明性。我们就以select这个组件为例,很多情况下,我们的select里面的option都是需要从数据库里面取数据的,所以一般的做法就是发送一个ajax请求,然后在success方法里面拼html。现在我们就封装一个select远程取数据的方法。

1、代码实现以及使用示例

先上干货吧,将写好的整出来:

(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");

其实对于简单的select标签,博主觉得这里的getValu和SetValue意义不大,因为直接通过$('#sel_search_plant').val()就能解决的事,何必要再封一层。这里仅仅是做演示,试想,如果是封装成类似select2或者multiselect这种组件,getValue和setValue的意义就有了,你觉得呢?

2、代码详细讲解

上面的实现代码,如果您一眼就能看懂,证明您是经常封组件的大虾了,下面的就不用看了。如果看不懂,也没关系,我们将代码拆开详细看看里面是什么鬼。

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

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

初初看到这种用法,博主也是狂抓,这是什么鬼嘛,四不像啊。使用多了之后才知道原来这就是一个匿名函数的形式。将它拆开来看如下:

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

也就是说这种写法就表示先定义一个方法,然后立即调用这个方法,jQuery相当于实参。打开jquery.js的原文件可以看到,jQuery是这个文件里面的一个全局变量。

(2)定义自己的组件的代码:

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

习惯这种写法的应该知道,这个就表示向jquery对象添加自定义方法,比如你想使用文章开始的 $("#id").MyJsControl({}) 这种用法,你就可以这样定义 $.fn.MyJsControl=function(options){} 。

(3) options = $.extend({}, $.fn.combobox.defaults, options || {}); 这一句,看过上文的朋友应该还记得extend这么一个方法吧,怎么样,又来了你。这句话其实就没什么好说的了,合并默认参数和用户传进来的参数。

(4)默认参数列表

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

如果用户没有传参,就用默认的参数列表。如果你够细心,你会发现博主之前分享的其他bootstrap组件的js文件里面都有这么一个default参数列表。我们随便找两个:

bootstrap上传组件

bootstrap table组件

基本都是这么些用法。这样来看,是否也可以自己封一个js组件~~

三、总结

以上就是博主对js组件扩展以及封装用法的认识和总结。当然,都是些比较简单基础的封装,如果想要实现类似bootstrap table的组件,那还差得很远。不过万丈高楼平地起,只要打好基础,封一个自己的table组件也不是什么大问题。文中如果有理解不对的地方,欢迎指出,博主将不胜感激。如果本文能够对你有丝毫帮助,麻烦抬起你的小手点个推荐,博主一定继续努力,将更好的文章分享给大家。

jquery extend函数相关推荐

  1. jQuery.extend 函数使用详解

    jQuery.extend 函数使用详解 一.总结 一句话总结: jquery $.extend的作用就是:用于将一个或多个对象的内容合并到目标对象:$.extend( target [, objec ...

  2. [zz]jQuery.extend 函数详解

    JQuery的extend扩展方法:       Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解.       一.Jquery的扩 ...

  3. jQuery.extend 函数详解

    JQuery的extend扩展方法: Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解. 一.Jquery的扩展方法原型 extend ...

  4. jQuery.extend函数

    2019独角兽企业重金招聘Python工程师标准>>> 1 扩展jQuery静态方法 $.extend({test:function(){alert('test函数');} }) 用 ...

  5. [转载]jQuery.extend 函数详解

    JQuery的extend扩展方法:       Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解.       一.Jquery的扩 ...

  6. jquery $.extend() 对象内容合并

    jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象. 注意: 1. 如果只为$.extend()指定了一个参数,则意味着参数target被省略.此时,target就是jQue ...

  7. jQuery.extend()方法

    定义和用法 jQuery.extend()函数用于将一个或多个对象的内容合并到目标对象. 注意: 1. 如果只为$.extend()指定了一个参数,则意味着参数target被省略.此时,target就 ...

  8. jquery06 jQuery.extend 给jQuery函数添加、继承 静态方法

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  9. JQuery模拟二------添加extend函数和简单选择器

    在原来的基础上添加extend函数和#id选择器 //自调函数把window这个全局变量传入 (function(){//把jQuery和$另存一份var _jQuery = window.jQuer ...

最新文章

  1. 反向R?削弱显著特征为细粒度分类带来提升 | AAAI 2020
  2. HTML Encode 编码在线转换工具
  3. IT兄弟连 JavaWeb教程 MVC设计模式
  4. java 信号量Semaphore
  5. 数据库-MySQL-高级查询-IN通配符LIKE
  6. 支持的存储类型有_跟我一起看博途1200系统手册之数据类型的介绍
  7. c# 如何读取和写入ini(配置文件)
  8. iOS 分组索引和索引分区
  9. 倒计时1天 | 一年学遍吴恩达、李飞飞、周志华等17大精品课!(ML、CV、NLP一应俱全)...
  10. jQuery知识点学习整理
  11. Windows远程桌面命令mstsc-远程桌面大小配置
  12. Tortoise SVN 1.8.11怎么汉化
  13. python3读取pdf文档;pdfminer3k
  14. Texstudio安装后闪退|重装系统Windows10|texstudio2022
  15. [渝粤教育] 山东职业学院 话说铁道 参考 资料
  16. 跨考计算机,一战398分成功上岸经验总结
  17. 人脸对齐之SDM论文解析
  18. socket编程之read()/write()
  19. 支付宝支付接口调用实现支付功能
  20. 给快马系统清理Fans的一些回复

热门文章

  1. Android 进程间通信 实例分析
  2. Linux基本命令之ls
  3. 华为鸿蒙系统多久上市,华为鸿蒙系统手机上市了吗 鸿蒙OS已达到安卓70-80%水平...
  4. Linux内核之浅谈内存寻址
  5. android汽车之家顶部滑动菜单,Android自定义控件之仿汽车之家下拉刷新
  6. matlab中如何画隐函数方程组,怎样用matlab画隐函数
  7. java oracle exp_java中使用oracle的exp/imp导出、导入数据
  8. php oracle创建临时表,Oracle常用命令笔记
  9. 怎么选?阿里P7 or 副处级干部?
  10. 每日一皮:就像我的编程,虽然过程不咋地,结果还不错...