1. 기존 구성 요소 확장
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({})를 캡슐화하고 캡슐화된 공용 메서드에서 오류에 해당하는 이벤트를 정의할 수 있습니다. 실제로 이는 우리의 요구 사항을 충족할 수 있지만 완벽하지는 않습니다. 이유는 매우 간단합니다. 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() 메서드를 어떻게 설명하는지 살펴보겠습니다.
무슨 뜻인가요? 두 가지 공식 사례를 통해 알아보겠습니다
밤 1 :
var settings = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; $.extend(settings, options);
결과:
settings == { validate: true, limit: 5, name: "bar" }
밤 2:
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()의 역할을 이해하면 위 확장자 jquery.ajax의 구현을 대략적으로 이해할 수 있습니다. 주요 단계는 다음과 같이 구분됩니다.
1) 기본 오류 처리 방법을 정의합니다.
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(){}을 사용자 정의했는지 확인합니다. 정의된 경우, 그렇지 않으면 기본 오류 처리 방법이 사용됩니다. 사용됩니다.
3) $.extend()를 사용하여 기본 오류 처리 방법을 $.ajax()의 매개변수에 전달합니다. options 매개변수를 보면 $.ajax() 메서드의 모든 매개변수가 포함되어 있으며 기본 fn을 사용하여 확장합니다.
위의 세 단계를 통해 $.ajax() 메서드에 기본 오류 처리 방법을 구현할 수 있습니다. 이번 확장을 통해 사용자는 $.ajax({});와 같은 ajax 요청을 계속 보낼 수 있습니다. 특별한 상황이 없으면 오류 처리 방법을 작성할 필요가 없습니다.
3.컴포넌트 확장의 의미
구성 요소 확장을 사용하면 시스템 비즈니스와 관련된 일부 처리 요구 사항을 원래 구성 요소에 추가하는 데 도움이 될 수 있습니다. 이를 사용할 때 기본 구성 요소를 사용하는 것처럼 계속 호출할 수 있으므로 다시 캡슐화할 필요가 없습니다. 부풀어 오른 층.
2. 자체 구성 요소 확장
$.ajax()의 오류 이벤트 처리 방법은 위에서 $.extend() 메서드를 통해 확장되었습니다. 우리 자신의 구성요소를 캡슐화해 보겠습니다. 함수는 매우 간단하지만 상대적으로 예시적입니다. select 구성 요소를 예로 들어 보겠습니다. 많은 경우 select의 옵션은 데이터베이스에서 데이터를 가져와야 하므로 일반적인 접근 방식은 ajax 요청을 보낸 다음 성공 메서드에 html을 입력하는 것입니다. 이제 원격 데이터 검색을 선택하는 방법을 캡슐화하겠습니다.
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);
먼저 맞춤 구성요소를 사용하는 방법을 살펴보겠습니다.
사용법 1: URL을 통해 원격으로 데이터 검색 및 초기화
먼저 빈 선택을 정의하세요
<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' }); })
매개변수는 매우 간단하므로 하나씩 소개하지는 않겠습니다. 엄청 간단한데 혹시 없나요~~
용법 2: 값 및 설정
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组件扩展以及封装用法的认识和总结,希望大家喜欢。