由于有个table需要用到的筛选条件比较多,不好全部列出来,故考虑做一个自定义筛选来满足需求。
首先定义一个下来框来选择需要筛选的条件(这里我直接列出了,也可以通过ajax获取):
<div class="layui-input-inline">
<select name = "abcde" id="abcde" >
<option value="">自定义条件</option>
<option value="uuid">UUID</option>
<option value="hostname">VM主机名</option>
<option value="cls">所在集群</option>
<option value="dnsname">DNS名称</option>
<option value="esxiip">ESXI_IP</option>
<option value="datasource">数据来源</option>
<option value="root_apply">Root开通状态</option>
<option value="level">业务级别</option>
<option value="os_type">操作系统</option>
</select>
</div>
然后定义一个input框来输入筛选条件的值:
<div class="layui-inline">
<div class="layui-input-inline">
<input class="layui-input" name="myfilter_value" id="myfilter_value" placeholder="自定义字段值" autocomplete="off">
</div>
</div>
我的项目是使用了layui-admin的模板,所以table的reload代码会有些不同,我这里直接放出来:
var $ = layui.$, active = {
reload: function(){
const ip = $('#ip');
const cname = $('#cname');
const os_type = $('#os_type');
const status = $('#status');
const abcde = $('#abcde');
const myfilter_value = $('#myfilter_value');
// 创建基础查询条件
const where = {
ip: ip.val(),
cname: cname.val(),
os_type: os_type.val(),
status: status.val(),
[abcde.val()]: myfilter_value.val()
};
table.reload('tabReload', {
page: { curr: 1 },
where: where
});
}
};
[abcde.val()]: myfilter_value.val() 这个是核心代码,通过这个把自定义条件和值赋值给了where传递到后端进行条件筛选。 由于是动态赋值,所以必须使用 [] 括起来。这个 [] 语法在 JavaScript 中被称为“方括号表达式”,它允许在运行时动态地计算属性名,从而实现动态属性访问。
调整了下后端服务,测试了下是能够实现参数的正常传递的。但是发现了一个新问题,那就是当我选了自定义条件并输入筛选值后,点击搜索按钮,这时候结果是正确的。然后我重新选择筛选字段,再输入筛选值,这时候点击搜索按钮,结果不是预期的。查看后端日志发现第二次搜索时把第一次的筛选条件也带上了,也就是会有两个筛选条件,导致结果不正确。
找了资料说是layui-table的reload方法会自动带上之前的参数,所以需要手动清除。然后我找到layui目录下的一个 table.js 文件,修改了源码,但是测试后还是有问题。然后就是反复折腾,觉得没找对地方修改,把能修改的都修改了,还是不行。
也是基础不扎实,没怎么搞过javascript,折腾了一天,才想到可以通过console.log 来判断是否有调用reload函数。加上console.log后,发现根本没有输出,也就是没用调用 table.js 里的reload函数。
继续排查,把涉及到的table的reload方法的js都研究了,最终发现是调用的 layui.all.js 文件里的。原来这个文件已经把layui相关的模块代码合并进去了,所以修改table.js是无效的。找到调用的函数位置:
d.reload=function(e,i){i=i||{};var a=s(e);if(a)return i.data&&i.data.constructor===Array&&delete a.data,d.render(t.extend(!0,{},a,i))}
这个函数里,e代表的是当前实例,i代表是新增加的参数。然后通过s(e)获取到当前实例的配置,然后通过t.extend(!0,{},a,i)把新参数合并到当前实例的配置里,然后调用d.render(t.extend(!0,{},a,i))重新渲染。所以我们需要在合并参数前,把当前实例配置里的条件清空。修改成以下:
d.reload=function(e,i){i=i||{};var a=s(e);a.where={};if(a)return i.data&&i.data.constructor===Array&&delete a.data,d.render(t.extend(!0,{},a,i))}
修改后问题测试通过!
还有个小问题要注意,下拉框不能设置为request 属性,否则当没有下拉选择,而其它基础条件存在时,重置条件就会报错导致不能正常清理基础条件。
...