需求:前端的多条件查询,特别涉及到并且/或者,还有包含/不包含
如图
所以查询得时候的考虑一些问题,具体如下:
1、目前查询的时候拿到的用户数据格式如下:
let data= [
{cond:
{
keyword:"年会",
operate:"$regex",//包含关系
},
{
keyword:"^((?!2019).)*$",
operate:"$regex",//不包含例子,统一处理为包含关系,区别在于keyword
}
},
relation:"$and",//并且/或者$or关系
}
]
2、目前是统一处理为包含关系,所以不包含得情况下需要转化一下数据
比如如果是选得不包含情形,进行处理为包含
2.1 、包含/不包含得html
//html
<select class="condition-search-select icon-aggrid-select relation">
<option value="$regex">包含</option>
<option value="nor">不包含</option>
</select>
2.2 、js不包含得数据处理为包含关系
//不包含得值得组装
if(this.el.find('.condition-search-select.relation').eq(i).val() == 'nor') {
let keyword = this.el.find('.condition-search-value').find('input').eq(i).val();
obj['cond']['operate'] = '$regex';
obj['cond']['keyword'] = `^((?!${keyword}).)*$`;
}
2.3 、组装并且/或者数据
//组装并且/或者数据
let filterSearchList = [];//并且的数据
let contactSearchList = [];//或者的数据
data.forEach(item=>{
if (item['relation']=='$and') {//并且
!filterSearchList.includes(item)&&filterSearchList.push(item['cond'])
}
else if (item['relation']=='$or') {//或者
!contactSearchList.includes(item)&&contactSearchList.push(item['cond'])
}
})
3、并且属于&&得关系,我用得fliter进行筛选循环,每一个并且数组里的keyword都需要满足,我这边是筛选了二次,第一次是从总数据里拿到都包含并且里得值得数据,第二次就是从第一次筛选得值里在进行筛选,拿到并集
//this.allWorkflow是总数据
//第一次筛选并且得每个值
//拿到不包含得数据后,需要判断一下
//第一:i['keyword'].includes('^((?!')我是通过这个判断是否是不包含关系
//第二:然后再通过new RegExp(i['keyword'])这种方法,把变量i['keyword']转化为正则
//第三:这样就可以使用test()正则验证方法,true得值就返回
for (let i of filterSearchList){
searchResult = this.allWorkflow.filter(item => {
return i['keyword'].includes('^((?!')
? new RegExp(i['keyword']).test(item['name'])
:item['name'].indexOf(i['keyword'])!=-1
});
}
//第二次筛选符合并且所有值得数据
for (let i of filterSearchList){
searchResult = searchResult.filter(item => {
return i['keyword'].includes('^((?!')
? new RegExp(i['keyword']).test(item['name'])
:item['name'].indexOf(i['keyword'])!=-1
});
}
}
4、或者属于||关系,也就是或者得keyword也都需要查询出来,所以我是写在并且筛选完数据后,并且最终的数据concat 全部数据中筛选符合或者条件得数据
//this.allWorkflow是总数据
if (contactSearchList.length!=0) {
for (let i of contactSearchList){
searchResult = searchResult.concat(this.allWorkflow.filter(item => {
return i['keyword'].includes('^((?!')
? new RegExp(i['keyword']).test(item['name'])
:item['name'].indexOf(i['keyword'])!=-1
}))
}
}
至此,一个前端的多条件查询,有包含/不包含,并且/或者得关系就弄好了,我们做一个需求之前,都是先理清楚思路,然后编写代码,当然思路肯定是编写代码的时候可能会越来越清晰或者进行优化完善,基于我目前公司的开发模式,我给出这样的一个思路,有更好的希望可以多多交流