一、前言
最近,被分配了一个需求要完成展示日志并且做到实时刷新展示。在此记录一下完成时的思路、遇到的困难以及解决方法
以下界面展示:

二、解决思路
1、展示界面:Modal
点击查看会进行日志展示,以弹窗的形式进行展示
2、日志展示:codemirror
毕竟是展示日志,所以使用代码编辑codemirror
3、实时更新数据:定时器
三、实现过程及遇到问题解决
1、在Table中添加查看一列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | { title: 'XX日志', key: 'log', dataIndex: 'log', render: (text,record) => { return ( <div> <a onClick={()=>this.showModal(record)}>查看</a> <Modal visible={this.state.visible} ... //设置符合自己需求的属性 > {logInfo} </Modal> </div> ) } } |
首先搭一个展示日志的架子
(1)点击查看(这里将其设置为a标签),点击触发事件onClick,设置visible(为bool类型)的true or false 来控制madal的显示或隐藏
(2)日志的内容写在{logInfo}中
出现问题:
(1)在modal弹出来的时候页面右侧会有两个滚动条
解决方法:在包裹modal的外层div中添加 style={{ overflow: 'hidden'}}
(2)自定义modal来符合自己使用要求(期望自定义右下角按钮以及不想要右上角的关闭小叉叉×)
解决方法:
去查看了官方文档,有一些实例和属性介绍还算比较全
① 通过设置 footer={[...]} 属性来实现自定义右下角按钮
以下是官方文档描述:

不太详细,但是有实例,可以去看一下代码。也可以搜索一下footer的用法。
其实挺简单的,就和平常定义
下面是这个需求中所需的自定义样式
1 2 3 4 5 6 7 8 9 | footer={[ <Button key="back" onClick={() => this.onCancel(record)} type="primary" > 确定 </Button> ]} |
2、获取日志数据
从后端调用接口在页面中进行展示,而实时更新就通过定时器不断刷新来调用接口。
步骤如下:
(1)在a标签的onClick事件中调用函数showModal保存调用后端接口时的请求参数
1 | <a onClick={()=>this.showModal(record)}>查看</a> |
1 2 3 4 5 6 7 8 9 10 11 12 | //显示Modal并且保存点击行信息 showModal(record) { const visible = this.state.visible visible[record.buildNum] = true if(record) { this.setState({ flowLine_Id: record.flowLine_Id, buildNum: record.buildNum, visible },() => this.showFullLog(this.state.flowLine_Id,this.state.buildNum)) } } |
(2)利用回调进行接口数据获取以及更新日志数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //全量日志展示 showFullLog(id, num) { let visible = this.state.visible if(id && num) { const params = {}; params.id = id; params.buildNum = num; if(visible[num]) { this.timer = setInterval(() => { axiosRequest(DI.getAllFlowLineLog, 'POST', params).then((json) => { if (json.code == 200) { if (!Func.isEmptyObject(json.result.logResult)) { console.log('showFullLog_logResult',json.result.logResult); this.setState({ codemirrorInfo: json.result.logResult.replace(/?/g, '\n') }) } } visible = this.state.visible if(!visible[num]){ clearInterval(this.timer); } }) }, 1500); } } } |
出现问题:
(1)不知道在Table中点击每行的数据是如何取到的
于是去看了官方文档,有如下描述:

在这里我发现,其中record就是每行的全部信息,只需要把需要的内容选取出来就可以了
(2)接口调用失败
用了打印、打断点的方式,发现请求参数为空。
于是我考虑应该是异步执行的问题,导致先走了showFullLog函数去调用接口,而其中的请求参数还没有取到
用了回调,解决问题
(3)实时更新数据
实时更新,后端接口的数据是在jekins上实时取得的,所以当时的想法就是不断地调用接口来获取数据。就想到使用定时器
而时候使用定时器,什么时候清除定时器是要解决的问题
在网上进行搜索,发现大多都是在生命周期函数中使用,但是我仅仅也就是知道生命周期函数是个什么意思,但具体实现让我觉得十分困惑,没有思路了。于是请教了我师傅。
我师傅和我说不一定要用生命周期函数,可以直接在调用接口的函数中使用定时器。以控制modal显示或隐藏的 visible 属性来控制定时器的创建和删除
按照这个思路,顺利地完成了实时更新日志要求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | if(visible[num]) { this.timer = setInterval(() => { axiosRequest(DI.getAllFlowLineLog, 'POST', params).then((json) => { if (json.code == 200) { if (!Func.isEmptyObject(json.result.logResult)) { this.setState({ codemirrorInfo: json.result.logResult.replace(/?/g, '\n') }) } } visible = this.state.visible if(!visible[num]){ clearInterval(this.timer); } }) }, 1500); } |
(4)modal遮罩层颜色很深
在有多条日志的情况下查看,modal的遮罩层颜色就会变得很深。打开控制台,就能都看见有多层modal被渲染出来
在网上查发现是因为多个Modal同时渲染和弹出造成的,并且这个问题场景是在table中使用modal
解决方法:
将visible设置为数组,通过判断规定id下的visible的值来控制只有一个modal被渲染和弹出
1 | visible: [], //对话框展示控制 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | {this.state.visible[record.buildNum] ? <Modal closable={false} footer={[ <Button key="back" onClick={() => this.onCancel(record)} type="primary" > 确定 </Button> ]} height={575} title="XX日志" visible={this.state.visible} width={810} > {logInfo} </Modal> : null } |
搜索解决遮罩层问题链接:https://www.cnblogs.com/ruoshuisanqian/p/10310679.html
3、codemirror展示日志数据
codemirror的使用,有官方文档,写的很详细了,可自行查看
网址:https://codemirror.net/doc/manual.html
我在CSDN找到的中文翻译的手册:https://blog.csdn.net/xiaohxx/article/details/89761737?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-2.channel_param
1 2 3 4 5 6 7 8 9 10 11 12 13 | //全量日志内容 let logInfo = ( <div> <CodeMirror onChange={(codemirrorObject,value) => codemirrorObject.getValue(value)} options={<!-- -->{ ... //自行添加适合的属性 }} value={this.state.codemirrorInfo} > </CodeMirror> </div> ) |
出现问题:
(1)给CodeMirror展示窗口添加滚动条
因为有的日志很长,比较迫切需要滚动条来进行上下拖动,而codemirror的滚动条添加是x轴、y轴都加,所以在其外面包裹了一层div,在div上添加滚动条
1 2 3 | <div style={<!-- -->{overflowY: scroll}}> ... </div> |
(2)将CodeMirror设置为只读型
只是展示日志,并不要求进行更改,就将其设置为只读,在官方文档中有所描述
在option中添加readOnly属性,设置为true
1 2 3 4 | options={<!-- -->{ ... readOnly:true }} |
我在另一篇文章中对CodeMirror的scrollbarStyle属性大致介绍了下,有兴趣可以看一下(但我知道大家没兴趣,嘿嘿(●ˇ?ˇ●))
网址:https://blog.csdn.net/all_might1/article/details/109595385
然后就能够展示了,嗯,完成
码字好累呀 ~