分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

select2的使用(ajax获取数据)

发布时间:2023-09-06 02:25责任编辑:熊小新关键词:暂无标签

最近项目中用到了select2来做下拉框,数据都是通过ajax从后台获取, 支持动态搜索等。

使用到的下拉框分有两种情况:

一种是直接发送ajax请求渲染列表;另一种因为查询回的数据有六万多条,导致整个页面卡顿,所以采用的是先让用户至少输入3个字以后再动态模糊查询数据。

基本的使用方法看官方文档就可以明白,但是在做模糊查询的时候遇到了一些问题,在此记录一下。

第一种情况的下拉框,先是封装了函数获取数据,并拼接了列表模版,然后设置templateSelection即可。

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,
        placeholder:‘请选择省份‘,
        templateSelection:  getProvinceList($(‘#addrProvince‘))
 })
 
第二种做法则是按照文档里的做法,初始化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"}] }; ???????????????????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元素上(会导致点击选项以后,选项并不会被选中)

解决方案:

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是这么处理的的

//source code
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,
})

  




 
 
 
 
 

select2的使用(ajax获取数据)

原文地址:https://www.cnblogs.com/deadbug/p/10088544.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved