Maison  >  Article  >  interface Web  >  Encapsulez vos propres compétences en composants JS_javascript

Encapsulez vos propres compétences en composants JS_javascript

WBOY
WBOYoriginal
2016-05-16 15:17:241259parcourir

1. Étendre les composants existants
1. Contexte de la demande
Souvent, nous utilisons jquery.ajax pour envoyer des requêtes en arrière-plan, telles que

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

      });

Ce genre de code est trop courant. En ce moment, nous avons un besoin : lorsque nous appelons la requête ajax, nous ne voulons pas écrire du code comme error:function(e){} à chaque fois, mais nous aussi. je le souhaite À chaque fois, le message d'erreur ajax est affiché sur le navigateur afin que l'utilisateur puisse le voir. Ce qu'il faut faire?

2.Principe de mise en œuvre
Il n'est pas difficile d'obtenir l'effet ci-dessus. Nous pouvons encapsuler $.ajax({}) et définir l'événement correspondant à l'erreur dans la méthode publique encapsulée. En effet, cela peut répondre à nos exigences, mais ce n'est pas parfait. Les raisons sont très simples : 1) Encapsuler une autre couche au-dessus de jquery n'est pas assez efficace 2) Les habitudes de l'appelant doivent être modifiées, et à chaque appel d'ajax ; , Nous ne voulons pas le voir écrit selon les règles de la méthode que nous avons définie, au lieu d'utiliser directement la méthode native $.ajax({}).

Dans ce cas, comment pouvons-nous répondre aux exigences ci-dessus sans encapsuler les contrôles ? La réponse est d'étendre le jquery.ajax natif via notre $.extend.

En fait, ce n'est pas difficile à mettre en œuvre. Nos exigences peuvent être satisfaites grâce au morceau de code suivant.

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

Si vous n'avez pas été exposé à la méthode $.extend dans jquery, vous ne comprendrez peut-être pas ce que signifie ce qui précède. Bon, voyons d'abord comment l'API jquery explique la méthode $.extend().

Qu'est-ce que cela signifie ? Regardons les deux exemples officiels pour le découvrir

Châtaigne 1 :

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

Résultat :

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

Châtaigne 2 :

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

Résultat :

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

Les deux exemples simples ci-dessus illustrent que la fonction de la méthode extend() est de fusionner un autre objet. S'il y a les mêmes objets, ils seront écrasés. S'il n'y a pas d'objets identiques, ils seront ajoutés. C'est aussi simple que cela.

Comprenant le rôle de $.extend(), nous pouvons à peu près comprendre l'implémentation de l'extension jquery.ajax ci-dessus. Les principales étapes sont divisées en :

1) Définissez la méthode de gestion des erreurs par défaut.

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) Déterminez si l'utilisateur a personnalisé error:function(){} lors de l'appel de $.ajax({}). S'il a été défini, celui défini par l'utilisateur sera utilisé. Sinon, la méthode de gestion des erreurs par défaut. sera utilisé.

3) Utilisez $.extend() pour transmettre la méthode de gestion des erreurs par défaut dans le paramètre de $.ajax(). Lorsque nous examinons le paramètre options, il inclut tous les paramètres de la méthode $.ajax(), puis utilise le fn par défaut pour le développer.

Grâce aux trois étapes ci-dessus, vous pouvez implémenter la méthode de gestion des erreurs par défaut dans la méthode $.ajax(). Avec cette extension, nos utilisateurs ne ressentiront pas du tout le changement. Nous pouvons toujours envoyer des requêtes ajax comme $.ajax({});. S'il n'y a pas de circonstances particulières, il n'est pas nécessaire d'écrire une méthode de gestion des erreurs.

3. La signification de l'extension de composant
L'utilisation d'extensions de composants peut nous aider à ajouter certaines exigences de traitement liées à notre activité système aux composants d'origine, nous pouvons toujours les appeler comme si nous utilisions des composants natifs, éliminant ainsi le besoin de les encapsuler à nouveau. couche de ballonnement.

2. Développez vos propres composants
La méthode de gestion des événements d'erreur de $.ajax() est étendue ci-dessus via la méthode $.extend(). Essayons d'encapsuler un de nos propres composants. La fonction est très simple, mais relativement illustrative. Prenons le composant select comme exemple. Dans de nombreux cas, les options de notre select doivent récupérer des données de la base de données, donc l'approche générale consiste à envoyer une requête ajax, puis à épeler html dans la méthode de réussite. Nous allons maintenant encapsuler une méthode pour sélectionner la récupération de données à distance.

1. Exemples d'implémentation et d'utilisation du code
Commençons par les aspects pratiques et écrivons-les :

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

Voyons d'abord comment utiliser nos composants personnalisés :

Utilisation 1 : Récupérer des données à distance via une URL et initialiser
Définissez d'abord une sélection vide

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

Puis initialisez-le

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

Les paramètres sont très simples, je ne les présenterai donc pas un par un. C'est très simple, y en a-t-il~~

Utilisation 2 : Valeur et réglage

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

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn