ホームページ  >  記事  >  ウェブフロントエンド  >  独自の JS コンポーネントのカプセル化_JavaScript スキル

独自の JS コンポーネントのカプセル化_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 15:17:241259ブラウズ

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() メソッドをどのように説明するかを見てみましょう。

それはどういう意味ですか? 2 つの公式の例を見てみましょう

栗 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" }

上記の 2 つの簡単な例は、extend() メソッドの機能が別のオブジェクトをマージすることであることを示しています。同じオブジェクトが存在しない場合、それらは上書きされます。それはとても簡単です。

$.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 を使用してそれを展開しています。

上記の 3 つの手順により、$.ajax() メソッドにデフォルトのエラー処理メソッドを実装できます。この拡張により、ユーザーは $.ajax({}); のような ajax リクエストを送信することができます。特別な事情がない限り、エラー処理メソッドを記述する必要はありません。

3. コンポーネント拡張の意味
コンポーネント拡張機能を使用すると、システム ビジネスに関連するいくつかの処理要件を元のコンポーネントに追加することができ、ネイティブ コンポーネントを使用する場合と同様にコンポーネントを呼び出すことができるため、コンポーネントを再度カプセル化する必要がなくなります。腫れの層。

2. 独自のコンポーネントを展開します
$.ajax() のエラー イベント処理メソッドは、$.extend() メソッドを通じて上記に拡張されています。独自のコンポーネントをカプセル化してみましょう。この関数は非常に単純ですが、比較的わかりやすいものです。例として select コンポーネントを見てみましょう。多くの場合、select のオプションはデータベースからデータをフェッチする必要があるため、一般的なアプローチは、ajax リクエストを送信してから、success メソッドで 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组件扩展以及封装用法的认识和总结,希望大家喜欢。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。