jquery extend函数

2023-11-02

 

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组件也不是什么大问题。文中如果有理解不对的地方,欢迎指出,博主将不胜感激。如果本文能够对你有丝毫帮助,麻烦抬起你的小手点个推荐,博主一定继续努力,将更好的文章分享给大家。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jquery extend函数 的相关文章

随机推荐

  • MobaXterm 突破14个session限制

    通常情况下 随着工作时间的增长 我们会保存许许多多的linux到本地的mobastream 然后当超过14个 就会被被限制 这个会让人很头疼 1 安装python 配置好环境变量 测试安装成功 2 基于项目进行解除限制 git clone
  • ListControl中判定双击哪一行哪一列

    NM DBLCLK消息 void CDBResultDlg OnNMDblclkListDb NMHDR pNMHDR LRESULT pResult int nRet 0 LVHITTESTINFO HitTestInfo LPNMITE
  • 代码审查(Code Review)

    1 代码审查概述 1 1 什么是代码审查 对计算机源代码系统化地审查 常用软件同行评审的方式进行 其目的是在找出及修正在软件开发初期未发现的错误 提升软件质量及开发者的技术 1 2 为什么要做代码审查 可以帮助提高代码质量 代码审查的初衷是
  • Geoscience knowledge graph in the big data era

    Geoscience knowledge graph in the big data era 记录我的学习心得 如有不妥 联系删除 Information 作者包括Chenghu ZHOU Hua WANG Chengshan WANG等人
  • 收到大量垃圾短信怎么办?如何屏蔽垃圾短信?

    手机要是突然收到大量垃圾短信 先不要急 原因可能是短信接口被刷 有人用大量短信轰炸来掩盖消费通知 什么意思呢 就是我们手机上各种购物APP或者第三方支付平台等会绑定银行卡 一些诈骗平台会通过大量短信轰炸来掩盖消费通知 就是银行卡被刷了 但是
  • vscoode中使用vue报错

    前言 为什么写了这篇笔记 因为今天我们学习了vue脚手架的知识 我最开始使用的是hb的命令控制台 他可以使用 我心血来潮 其实是因为vscode的美化太好了 想使用vscode打开vue的脚手架 所以我满怀期待的打开了vscode 1 报错
  • Hadoop总结之HDFS-Client端向HDFS中读写数据的流程

    一 Client向HDFS中存入数据 1 客户端通过Distributed FileSystem模块向NameNode请求上传文件 NameNode检查目标文件是否已存在 父目录是否存在 2 NameNode返回是否可以上传 不能上传会返回
  • 用Java编写,要求输出1~100内的素数。

    public class SuShu public static void main String args for int i 2 i lt 100 i boolean isSuShu true for int j 2 j
  • 接口(interface)和抽象类(abstract)的特点和区别

    接口 interface 和抽象类 abstract 的共同点和区别 进入这个话题之前我们先思考一下以下几个问题 1 我们为什要使用抽象类和接口 2 使用抽象类和接口有什么好处 3 我们在设计复杂程序时该怎么合理使用抽象类和接口 抽象类的特
  • huggingface tokenizers

    专注 NLP 的初创团队抱抱脸 hugging face 发布帮助自然语言处理过程中 更快的词语切分 tokenization 工具 Tokenizers 只要 20 秒就能编码 1GB 文本 功能多样 适用于 BPE byte level
  • Bootstrap typeahead使用问题记录及解决方案

    简单介绍 Bootstrap typeahead插件是用来完成输入框的自动完成 模糊搜索和建议提示的功能 支持ajax数据加载 类似于jquery的流行插件Autocomplete typeahead的使用方式有两种 通过数据属性字段的方式
  • 计算机网络 将TCP封装成CTCP类

    首先我们在之前TCP的基础上 进行了优化 解决了粘包问题 这里的解决方式是 在包头给出包的大小 接收端接收到包时 先解析出包的大小 再根据大小分配空间 解决粘包代码 SOCKET sockWaiter my map GetCurrentTh
  • 学生信息管理系统(C语言版+详解+源代码)

    我二二学生信息管理系统 C语言版 详解 源代码 相信受这篇的都是为了期末项目而发愁吧 那么这篇文章最适合你了 我送给大家保姆级的教程 一 相信有部分同学不知道用什么软件运行吧 知道的可以直接看二哦 我用的软件是Devc 给大家发个链接 期末
  • 微信小程序换行 br 无效解决方法

    在微信小程序中 不识别 br 等标签 如果文字中想要折行显示 可以使用 n替代 br 注意 使用 n的时候 一定是在
  • 报错解决:APIConnectionError 调用异常处理 (openAI api)

    1 报错 raise error APIConnectionError openai error APIConnectionError Error communicating with OpenAI HTTPSConnectionPool
  • 26岁曾月薪15K,现已失业3个月,我依然没有拿到offer......

    我做测试5年 一线城市薪水拿到15K 中间还修了一个专升本 这个年限不说资深肯定也是配得上经验丰富的 今年行情不好人尽皆知 但我还是对我的薪水不是很满意 于是打算出去面试 希望可以搏一个高薪 但真到面试环节几个问题就把我问懵了 有没有做过接
  • CH6- JS UI前端开发

    文章目录 前言 目标 1 JS前端开发基础 JS FA的使用 AceAbility 如何加载JS FA JS FA开发目录 2 个典型JS FA应用开发 构建页面结构 构建页面样式 构建页面逻辑 适配设备类型 3 构建用户界面 组件通用特性
  • 普利姆算法(Prim)

    普利姆算法和克鲁斯卡尔算法都是求连接图中所有结点的最短路径 也就是最小生成树 普利姆算法其实就是不断获取已经访问结点和未访问结点之间的最短边来获取所有结点间的最短路径 也可以认为是广度 贪婪 接下来看算法的实现 这里只给出关键代码 基本的图
  • 定时器开始时延时了十几秒_第六章--系统滴答定时器

    第六章 系统滴答定时器 简介 系统滴答定时器是内核 这里指M4 定时器使用的是内核时钟源168MZ或可以选择外部时钟源21MZ 应用场合 为UCOS系统提供时钟节拍 作为简单的定时器延时使用 最大延时798ms 作为定时器中断使用 1 sT
  • jquery extend函数

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