当下拉列表,从后端获取列表数据,数据量上万条时,如果直接将查询的结果渲染到前端页面,效率是非常低的。我的解决方案是,每次从后端读取100条数据(当然你可以自己限定每次查询的条数),当用户在列表框输入数据进行筛选时,再通过模糊查询从后端查询100条数据,用户输的数据越精确,匹配度越高。下面是具体代码:
1、如果前端代码用easyui实现:
(1) html代码
div中定义了一个input输入框以及span标签
<div>
<span class='title'>下拉框</span>
<input id='options' />
</div>
(2)js代码
发送ajax异步请求,加载下拉框数据,定义了param来传参数,初始化参数值为空,发送请求成功之后,通过eaysui将input输入框创建为下拉框。textField为下拉框文本字段,valueField为下拉框值字段,editable设置为true,使得下拉框可编辑,方便模糊查询从后台检索数据。然后设置了下拉框的宽度,以及下拉框面板的宽度。最后通过data属性,将从后台查询到的json数据集赋值到下拉框选项。后面是一个onChange事件,当我们在下拉框字段值改变的时候就会触发。
其中:onChange:function(v,o)v表示下拉框新值,o表示下拉框旧值。因此我将新值赋值给iName作为发送请求的参数,也就是后台模糊查询的条件数据。当onChange事件触发时,就会再次发送带参数的ajax请求。然后通过 loadData 方法,将从后台模糊查询到的数据赋值给它,从而加载本地列表数据。
param:{
iName:''
},
that.ajaxDeal("/getOptions",that.param,function(result){
if (result.code !== 200) {
return;
}
$("#options").createCombobox({
textField: "iName",
valueField: "iName",
editable:true,
width: 190,
panelWidth:400,
data: result.data,
onChange:function (v,o) {
that.param2.iName=v;
that.ajaxDeal("/getOptions",that.param,function(result) {
if (result.code !== 200) {
return;
}
$("#options").combobox('loadData',result.data);
});
}
});
},null,false,"post");
2、如果前端代码用vue+elementui实现
这是elementui实现的select选择器,filterable表示数据是否可搜索,filter-method表示搜索时触发的方法。
<el-select v-model="listQuery.bondCode" filterable :filter-method="searchBondByName" title="证券名称" placeholder="证券名称" class="form-input-item" clearable >
<el-option v-for="item in bondOptions" :key="item.oCode" :label="item.bName"
:value="item.oCode+'-'+item.bName+'-'+item.poolName+'-'+item.poolId">
</el-option>
</el-select>
getList方法用来获取下拉框数据,query是请求参数,初始化调用时,query中的数据是为空的,但是当在下拉框中输入了数据,
触发搜索方法searchBondByName时,会将输入框中的数据作为请求参数发送到后台。从而将请求返回的数据再赋值给下拉框 绑定的数据,就可以立即生效。
methods: {
getList: function() {
let query=this.listQuery;
getBondList(query).then(response => {
this.bondOptions = response.data;
}).catch(error => {
this.$notify.error({ title: "获取下拉框数据列表",message: error,duration: 2000 });
});
},
searchBondByName:function(inputKey){
//inputKey为当前输入的数据
this.listQuery.bondName = inputKey;
let query =this.listQuery;
getBondList(query).then(response => {
this.bondOptions = response.data;
})
},
}
3、后端代码sql语句
控制层和服务层代码无异,主要在sql语句中加了一条限制查询行数的语句。然后因为'<'号跟xml 标签冲突,所以需要转义,
还可以通过 ‘<’ 进行转义。
select t.o_code,t.b_name from tbnd t
<if test="i_Name != null and i_Name !='' ">
where and t.B_NAME like CONCAT('%',CONCAT(#{query},'%'))
</if>
and ROWNUM <![CDATA[<=]]>100