select2的使用(ajax獲取數據)

最近項目中用到了select2來作下拉框,數據都是經過ajax從後臺獲取, 支持動態搜索等。html

使用到的下拉框分有兩種狀況:ajax

一種是直接發送ajax請求渲染列表;另外一種由於查詢回的數據有六萬多條,致使整個頁面卡頓,因此採用的是先讓用戶至少輸入3個字之後再動態模糊查詢數據。json

 

基本的使用方法看官方文檔就能夠明白,可是在作模糊查詢的時候遇到了一些問題,在此記錄一下。數據結構

第一種狀況的下拉框,先是封裝了函數獲取數據,並拼接了列表模版,而後設置templateSelection便可。app

複製代碼

function getProvinceList(ele) {
        var proList = '<option value="-1">--省--</option>'
        $.ajax({
            type:'get',
            contentType:'application/json;charset=utf-8',
            url: dicUrl + 'queryTwoLayerAddress',
            dataType:'json',
            success: function(res) {
                if(status == 00) {          
                    var resArr = res.data
                    for( var i = 0; i < resArr.length; i++) {
                        proList += '<option value = '+ resArr[i].code +'>'+ resArr[i].codeText +'</option>'     
                    }               
                    ele.html(proList)           
                }   
            }
        })
    }

$('#addrProvince').select2({函數

 

        language: localLang,post

 

        placeholder:'請選擇省份',this

 

        templateSelection:  getProvinceList($('#addrProvince'))lua

 

 })url

 

複製代碼

 

第二種作法則是按照文檔裏的作法,初始化select框後再發送ajax請求.

複製代碼

$('#bankName').select2({
        minimumInputLength:3,
        id: function(data) {     //把[{id:1, text:"a"}] 轉換成[{data.id:1, data.codeText:"a"}], 由於後臺返回的數據是[{id:1, codeText:"a"}]
            return data.id
        },
       // text: function(data) {return data.codeText},   //不生效
        formatSelection: function (data) { return data.codeText },  //生效
        ajax: {
            type:'get',
            url: function(params){      
                return dicUrl + 'query/bankCode/'+ params.term
            },
            dataType:'json',    
            data: function(params) { //輸入的內容
                return {
                    text:params.term,
                }
            },  
            processResults: function (data, page) {
                //data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
                //須要將查出來的數據轉換成{id:***,text:***},不然點擊下拉框的時候沒法賦值
                    var array = data.data;
                    var i = 0;
                    while(i < array.length){
                            array[i]["id"] = array[i]['code'];
                            array[i]["text"] = array[i]['codeText'];
                            delete array[i]["ItemId"];
                            delete array[i]["ItemText"];
                    i++;
                    }
                    return { results: array };
                },  
            cache: true,        
        },
        placeholder:'請選擇銀行名稱',
        escapeMarkup: function(markup) { //提示語
            return markup
        },  
        templateResult: formatRepo,
        templateSelection: formatRepoSelection  
    });

    function formatRepo (repo) {
        if (repo.loading) {
            return repo.text;
        }   
        var markup = "<div class='select2-result-repository clearfix'>" +
            "<div class='select2-result-repository__meta'>" +
                "<div class='select2-result-repository__title'>" + repo.codeText + "</div>";    
        if (repo.description) {
            markup += "<div class='select2-result-repository__description'>" + repo.description + "</div>";
        }
        return markup;
    }
    
    function formatRepoSelection (repo) {
        return repo.text;
    }

複製代碼

 

select2.js 默認的ajax.results 返回的數據結構是 [{id:1,text:"a"},{id:2,text:"b"}, ...].

 

select2.js

//source code
* @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
*      The expected format is an object containing the following keys:
*      results array of objects that will be used as choices
*      more (optional) boolean indicating whether there are more results available
*      Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}
源碼中在ajax的success函數中回調ajax.results

複製代碼

//source code
success: function (data) {
     // TODO - replace query.page with query so users have access to term, page, etc.
     // added query as third paramter to keep backwards compatibility
     var results = options.results(data, query.page, query);
     query.callback(results);
}

複製代碼

 其實ajax.results是把請求回的數據在傳遞給query.callback以前先格式化成 [{id:a,text:"a"},{id:b,text:"b"}, ...]。

複製代碼

//source code
callback: this.bind(function (data) {

                    // ignore a response if the select2 has been closed before it was received
                    if (!self.opened()) return;


                    self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
                    self.postprocessResults(data, false, false);

                    if (data.more===true) {
                        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
                        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
                    } else {
                        more.remove();
                    }
                    self.positionDropdown();
                    self.resultsPage = page;
                    self.context = data.context;
                    this.opts.element.trigger({ type: "select2-loaded", items: data });
                })});

複製代碼

 

 query.callback則處理一些邏輯,確保下拉框選項被選中時觸發 .selectChoice。

複製代碼

//source code
selectChoice: function (choice) {

            var selected = this.container.find(".select2-search-choice-focus");
            if (selected.length && choice && choice[0] == selected[0]) {

            } else {
                if (selected.length) {
                    this.opts.element.trigger("choice-deselected", selected);
                }
                selected.removeClass("select2-search-choice-focus");
                if (choice && choice.length) {
                    this.close();
                    choice.addClass("select2-search-choice-focus");
                    this.opts.element.trigger("choice-selected", choice);
                }
            }
        }

複製代碼

 

所以,若是results格式錯誤,就會致使在執行.selectChoice的時候.select2-search-choice-focus不能被添加到DOM元素上(會致使點擊選項之後,選項並不會被選中)

解決方案:

1

2

3

4

5

6

7

8

9

10

11

12

13

results: function (data, page) {

  //data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };

    var array = data.results;

    var i = 0;

    while(i < array.length){

        array[i]["id"] = array[i]['ItemId'];

        array[i]["text"] = array[i]['ItemText'];

        delete array[i]["ItemId"];

        delete array[i]["ItemText"];

    i++;

    }

    return { results: array };

  }

  

也能夠手動更改對象的屬性名.

select.js是這麼處理的的

1

2

3

4

5

6

7

8

9

10

11

12

//source code<br>id: function (e) { return e == undefined ? null : e.id; },

    text: function (e) {

      if (e && this.data && this.data.text) {

        if ($.isFunction(this.data.text)) {

          return this.data.text(e);

        else {

          return e[this.data.text];

        }

      else {

        return e.text;

      }

    },

因此,咱們只要添加函數就能夠覆蓋默認的對象屬性名了。

$('#mySelect').select2({

  id: function (item) { return item.ItemId },

  // text: function (item) { return item.ItemText }, //not work  formatSelection: function (item) { return item.ItemText } //works

});

  

另外一個遇到的問題就是語言本地化。

發現直接引入語言包並不生效,因此直接使用函數改寫了提示語言。

var localLang = {

        noResults: function() {

            return '未找到匹配選項'

        },

        inputTooShort: function (args) {

            var remainingChars = args.minimum - args.input.length;

            var message = '請輸入' + remainingChars + '個或更多文字';

            return message;

        },

        searching: function () {

            return '搜索中…';

            }   

    }

 

 $('#select2').select2({

     language: localLang,

})

 

獲取選中的名

 var cardTypeW = $("#cardType option:checked").text();

獲取選中的值

寫法1

var cardTypeW = $("#cardType option:checked").val();

寫法2

var cardTypeW = $("#cardType").find("option:selected").val();

相關文章
相關標籤/搜索