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

二、解决思路
1、展示界面:Modal
点击查看会进行日志展示,以弹窗的形式进行展示
2、日志展示:codemirror
毕竟是展示日志,所以使用代码编辑codemirror
3、实时更新数据:定时器
三、实现过程及遇到问题解决
1、在Table中添加查看一列
{
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的用法。
其实挺简单的,就和平常定义<Button>时没什么区别,只不过是在footer里面写
下面是这个需求中所需的自定义样式
footer={[
<Button
key="back"
onClick={() => this.onCancel(record)}
type="primary"
>
确定
</Button>
]}
2、获取日志数据
从后端调用接口在页面中进行展示,而实时更新就通过定时器不断刷新来调用接口。
步骤如下:
(1)在a标签的onClick事件中调用函数showModal保存调用后端接口时的请求参数
<a onClick={()=>this.showModal(record)}>查看</a>
//显示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)利用回调进行接口数据获取以及更新日志数据
//全量日志展示
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 属性来控制定时器的创建和删除
按照这个思路,顺利地完成了实时更新日志要求
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被渲染和弹出
visible: [], //对话框展示控制
{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
//全量日志内容
let logInfo = (
<div>
<CodeMirror
onChange={(codemirrorObject,value) => codemirrorObject.getValue(value)}
options={{
... //自行添加适合的属性
}}
value={this.state.codemirrorInfo}
>
</CodeMirror>
</div>
)
出现问题:
(1)给CodeMirror展示窗口添加滚动条
因为有的日志很长,比较迫切需要滚动条来进行上下拖动,而codemirror的滚动条添加是x轴、y轴都加,所以在其外面包裹了一层div,在div上添加滚动条
<div style={{overflowY: scroll}}>
...
</div>
(2)将CodeMirror设置为只读型
只是展示日志,并不要求进行更改,就将其设置为只读,在官方文档中有所描述
在option中添加readOnly属性,设置为true
options={{
...
readOnly:true
}}
我在另一篇文章中对CodeMirror的scrollbarStyle属性大致介绍了下,有兴趣可以看一下(但我知道大家没兴趣,嘿嘿(●ˇ∀ˇ●))
网址:https://blog.csdn.net/all_might1/article/details/109595385
然后就能够展示了,嗯,完成
码字好累呀 ~
更多推荐
所有评论(0)