一、前言

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

以下界面展示:

 

 

二、解决思路

 

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

我在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

//全量日志内容
  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

 

 

然后就能够展示了,嗯,完成

码字好累呀 ~

更多推荐