标签:String orderType ivu orderKey key table 排序 iview
最近遇到一个需求,在iview中使用table实现多列排序,主要思路就是从前端获取排序字段集合,后端动态拼接sql语句;本想着挺简单的,可实操的时候还是有些小波折的,现把实现过程记录一下:
1.ivew前端获取排序集合
在iview
官网中table
组件的排序方法如下,在定义column
时设置sortable:true
属性,也可以实现数据排序,但这种排序是单页面排序,或前端排序,并未重新请求后台数据,并不符合我们的要求。
在需要排序的columu
中添加属性sortable:‘custom’
,在table
组件中监听on-sort-change
事件。
<Table stripe border @on-sort-change="sortChanged" :row-class-name="rowClass"
:columns="columns2" :data="rows" :highlight-row="highlight_row"
@on-selection-change="rowSelectChange" @on-row-click="onRowClick"
@on-current-change="currentRowChange" :height="height" >
</Table>
data() {
return {
//排序字段
orderKey:[],
// 排序类别(asc,desc)
orderType:[],
//排序的字段顺序(从0开始)(设置样式时使用)
sortIndex:[],
// 排序类别(asc,desc,normal)(设置样式时使用)
sortType:[],
columns: [{
title: 'Date',
key: "date",
sortable:'custom',
sortNumber: 0 ,
},{
title: 'Name',
key: 'name',
},{
title: 'Age',
key: 'age',
sortable:'custom',
sortNumber: 1 ,
},{
title: 'Address',
key: 'address',
},],
}
}
sortChanged: function({ column, key, order }) {
//order值可能为asc,desc,normal(不排序)
let k = [];let t = [];
k = this.orderKey
t = this.orderType
if(k.includes(key)){
let i = this.printArray(k,key);
if(order==='normal'){
k.splice(i,1)
t.splice(i,1)
}else{
t.splice(i,1,order)
}
}else{
k.push(key)
t.push(order)
}
this.orderKey = k
this.orderType = t
this.handleTheadAddClass(column,order)
this.reload()
},
//返回某元素在数组中下标
printArray(k,key){
for(let i=0;i<k.length;i++){
if(k[i]==key){
return i
}
}
},
在设置iview table样式的时候有点头疼,排序是由上下两个箭头组成的,经过调试得知,点击Date升序的时候,上箭头的class由ivu-icon ivu-icon-md-arrow-dropup
变为ivu-icon ivu-icon-md-arrow-dropup on
,同时颜色变为蓝色选中;再次点击列Date的上箭头取消排序时,其class又由ivu-icon ivu-icon-md-arrow-dropup on
变回ivu-icon ivu-icon-md-arrow-dropup
,同时箭头颜色变为灰色。猜想iview是通过移除或添加箭头元素的class属性来达到控制样式的目的的,果然在iview.css中找到了与之对应的css代码.ivu-table-sort i.on{color:#2d8cf0}
(ivu-table-sort为箭头父元素的class,i标签为箭头元素);现在的问题在于,当再次点击Age的升序时,Date的升序选中样式会被取消,那么如何保留样式呢,或者可不可以由我们自己重新设置样式呢,目前想到的是使用dom
的getElementsByClassName
方法得到组件,通过动态设置id的方式自己管理排序的选中状态,如果有更好的方法请告诉我哈~
在设置样式handleTheadAddClass
方法中,column.sortNumber
为自己设置的属性,即table中第几个需要排序的列,因为需要通过找类名的方式找到对应的节点,所以一定要按照顺序写啊(从0开始)。
// 标题行样式改变事件
handleTheadAddClass(column,order){
let i =[];let s = [];
i= this.sortIndex
s= this.sortType
let key = column.sortNumber
if(i.includes(key)){
let t = this.printArray(i,key);
s.splice(t,1,order)
}else{
i.push(key)
s.push(order)
}
this.sortIndex = i
this.sortType = s
for(let a = 0; a<this.sortIndex.length; a++){
let udom = document.getElementsByClassName("ivu-icon ivu-icon-md-arrow-dropup")[i[a]]
let ddom = document.getElementsByClassName("ivu-icon ivu-icon-md-arrow-dropdown")[i[a]]
udom.removeAttribute('id');
ddom.removeAttribute('id');
if(s[a]==="asc"){
udom.id = "select-sort"
}
if(s[a]==="desc"){
ddom.id = "select-sort"
}
}
},
2.后端动态查询
为了安全,一般我们都不会把数据库字段暴露给前端,前端传来的字段和数据库字段并不是正好对应的,需要我们自己转化一下。
在我们的实体VO中,加入三个属性,注意补全get和set方法。
/**
* 排序标识(不允许出现数据库字段名称)
*/
private String orderKey;
/**
* 排序类型(升序(asc)、降序(desc))
*/
private String orderType;
/**
* 排序map
*/
private Map<String,String> sortMap;
加入我们的转化类。
public class SortMapRequest implements Serializable{
private static final long serialVersionUID = -7746939983296484048L;
/**
* 排序标识(不允许出现数据库字段名称)
*/
private String orderKey;
/**
* 排序类型(升序(asc)、降序(desc))
*/
private String orderType;
public SortMapRequest(String orderKey, String orderType) {
this.orderKey = orderKey;
this.orderType = orderType;
}
public String getOrderKey() {
return orderKey;
}
public void setOrderKey(String orderKey) {
this.orderKey = orderKey;
}
public String getOrderType() {
return orderType;
}
public void setOrderType(String orderType) {
this.orderType = orderType;
}
public static Map<String, String> getSort(SortMapRequest request) {
//使用LinkedHashMap,排序是有顺序的
Map<String, String> sortmap = new LinkedHashMap<>();
String[] keys = request.getOrderKey().split(",");
String[] types = request.getOrderType().split(",");
for (int i = 0; i < keys.length; i++) {
if ("date".equals(keys[i])) {
//替换成你数据库中对应的字段
sortmap.put("Date", "Date" + types[i]);
} else if ("indexNumber".equals(keys[i])) {
sortmap.put("INDEX_NUMBER","INDEX_NUMBER "+ types[i]);
}
}
Map<String, String> resultMap = new LinkedHashMap<>();
for (Map.Entry<String, String> entry : sortmap.entrySet()) {
String key = entry.getKey();
resultMap.put(key, entry.getValue());
}
return resultMap;
}
}
然后在我们的service实现类里调用就可以啦,示例如下。
//PageBean 是一个分页对象
public Page<UserVO> queryPageList(PageBean pageBean, UserVOquery){
// 获取前台多列排序map
Map<String,String> map= SortMapRequest.getSort(
new SortMapRequest(query.getOrderKey(), query.getOrderType()));
if(!map.isEmpty()){
//将排序map设置为参数传递到mapper层
query.setSortMap(map);
}
List<UserVO> list = userMapper.queryPageList(pageBean,query);
return new Page<>(list , pageBean);
}
然后是mapper的XML文件的写法。
<select id="queryPageList" resultMap="queryPageListResultMap" parameterType="java.util.HashMap">
select
user.*, role.*
from SYS_USER user
LEFT JOIN SYS_ROLE_RELA role
ON user.ID = role.UID
ORDER BY
<choose>
<when test="vo.sortMap!= null and vo.sortMap!=''">
<!--用vo.sortMap.values()获取map的值-->
<foreach collection="vo.sortMap.values()" item="value" separator=",">
<!--增加前缀-->
<trim prefix="user.">
${value}
</trim>
</foreach>
</when>
<otherwise>
user.id ASC
</otherwise>
</choose>
</select>
好,到此多列排序就完成了,可能还存在一些问题,再慢慢改进吧!
标签:String,orderType,ivu,orderKey,key,table,排序,iview 来源: https://blog.csdn.net/William_Franca/article/details/95172850
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。