Heim  >  Artikel  >  Web-Frontend  >  Kapseln Sie Ihre eigenen JS-Komponenten_Javascript-Kenntnisse

Kapseln Sie Ihre eigenen JS-Komponenten_Javascript-Kenntnisse

WBOY
WBOYOriginal
2016-05-16 15:17:241259Durchsuche

1. Vorhandene Komponenten erweitern
1. Hintergrund der Nachfrage
Oft verwenden wir jquery.ajax, um Anfragen an den Hintergrund zu senden, wie zum Beispiel

$.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 () {
        }

      });

Diese Art von Code kommt derzeit zu häufig vor: Wenn wir die Ajax-Anfrage aufrufen, möchten wir nicht jedes Mal Code wie „error:function(e){}“ schreiben Ich möchte, dass die Ajax-Fehlermeldung jedes Mal an den Browser ausgegeben wird, damit der Benutzer sie sehen kann. Was zu tun?

2. Umsetzungsprinzip
Es ist nicht schwierig, den oben genannten Effekt zu erzielen. Wir können $.ajax({}) kapseln und das dem Fehler entsprechende Ereignis in der gekapselten öffentlichen Methode definieren. Dies kann zwar unsere Anforderungen erfüllen, ist aber nicht perfekt. Die Gründe sind sehr einfach: 1) Das Kapseln einer weiteren Ebene über Jquery ist nicht effizient genug. 2) Die Gewohnheiten des Anrufers müssen geändert werden, und zwar jedes Mal, wenn Ajax aufgerufen wird , Wir möchten nicht, dass es nach den Regeln der von uns definierten Methode geschrieben wird, anstatt direkt die native Methode $.ajax({}) zu verwenden.

Wie können wir in diesem Fall die oben genannten Anforderungen erreichen, ohne Steuerelemente zu kapseln? Die Antwort besteht darin, die native jquery.ajax durch unser $.extend zu erweitern.

Tatsächlich ist die Implementierung nicht schwierig. Unsere Anforderungen können durch den folgenden Code erreicht werden.

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

Wenn Sie die Methode $.extend in jquery noch nicht kennengelernt haben, verstehen Sie möglicherweise nicht, was das oben Genannte bedeutet. Okay, schauen wir uns zunächst an, wie die JQuery-API die Methode $.extend() erklärt.

Was bedeutet das? Schauen wir uns die beiden offiziellen Beispiele an, um das herauszufinden

Kastanie 1:

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

Ergebnis:

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

Kastanie 2:

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

Ergebnis:

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

Die beiden oben genannten einfachen Beispiele veranschaulichen, dass die Funktion der Methode „extend()“ darin besteht, ein anderes Objekt zusammenzuführen. Wenn es dieselben Objekte gibt, werden diese überschrieben. Wenn keine identischen Objekte vorhanden sind, werden sie hinzugefügt. So einfach ist das.

Wenn wir die Rolle von $.extend() verstehen, können wir die Implementierung der obigen Erweiterung jquery.ajax grob verstehen. Die Hauptschritte sind unterteilt in:

1) Definieren Sie die Standardmethode zur Fehlerbehandlung.

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) Stellen Sie fest, ob der Benutzer beim Aufruf von $.ajax({}) eine benutzerdefinierte Fehlerbehandlungsmethode verwendet hat verwendet wird.

3) Verwenden Sie $.extend(), um die Standardmethode zur Fehlerbehandlung an den Parameter von $.ajax() zu übergeben. Wenn wir uns den Optionsparameter ansehen, enthält er alle Parameter in der Methode $.ajax() und verwendet dann den Standard-FN, um ihn zu erweitern.

Durch die oben genannten drei Schritte können Sie die Standardmethode zur Fehlerbehandlung in der Methode $.ajax() implementieren. Mit dieser Erweiterung werden unsere Benutzer die Änderung überhaupt nicht spüren. Wir können weiterhin Ajax-Anfragen wie $.ajax({}); senden. Wenn keine besonderen Umstände vorliegen, ist es nicht erforderlich, eine Fehlerbehandlungsmethode zu schreiben.

3. Die Bedeutung der Komponentenerweiterung
Die Verwendung von Komponentenerweiterungen kann uns helfen, einige Verarbeitungsanforderungen im Zusammenhang mit unserem Systemgeschäft zu den ursprünglichen Komponenten hinzuzufügen. Wenn wir sie verwenden, können wir sie weiterhin wie bei der Verwendung nativer Komponenten aufrufen, sodass wir sie nicht erneut kapseln müssen Schicht Blähungen.

2. Erweitern Sie Ihre eigenen Komponenten
Die Fehlerereignisbehandlungsmethode von $.ajax() wird oben durch die Methode $.extend() erweitert. Versuchen wir, eine eigene Komponente zu kapseln. Die Funktion ist sehr einfach, aber relativ anschaulich. Nehmen wir als Beispiel die Auswahlkomponente. In vielen Fällen müssen die Optionen in unserer Auswahl Daten aus der Datenbank abrufen. Daher besteht der allgemeine Ansatz darin, eine Ajax-Anfrage zu senden und dann HTML in der Erfolgsmethode zu buchstabieren. Jetzt werden wir eine Methode zur Auswahl des Remote-Datenabrufs kapseln.

1. Beispiele für Code-Implementierung und -Nutzung
Beginnen wir mit den praktischen Dingen und schreiben wir es auf:

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

Werfen wir zunächst einen Blick auf die Verwendung unserer benutzerdefinierten Komponenten:

Verwendung 1: Daten per Fernzugriff über URL abrufen und initialisieren
Definieren Sie zunächst eine leere Auswahl

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

Dann initialisieren Sie es

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

Die Parameter sind sehr einfach, daher werde ich sie nicht einzeln vorstellen. Es ist ganz einfach, gibt es welche?~

Verwendung 2: Wert und Einstellung

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组件扩展以及封装用法的认识和总结,希望大家喜欢。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn