JS組件系列——封裝自己的JS組件


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) { } };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM