自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用Antd表格組件實(shí)現(xiàn)日程表

開(kāi)發(fā) 前端
20多天前,遇到一個(gè)日程表的業(yè)務(wù)需求,可以動(dòng)態(tài)增加列、對(duì)單元格進(jìn)行合并,結(jié)合公司的jsp項(xiàng)目的已有功能完成單元格的增、刪、改操作。

[[353267]]

本文轉(zhuǎn)載自微信公眾號(hào)「神奇的程序員K」,作者神奇的程序員K 。轉(zhuǎn)載本文請(qǐng)聯(lián)系神奇的程序員K公眾號(hào)。

 前言

20多天前,遇到一個(gè)日程表的業(yè)務(wù)需求,可以動(dòng)態(tài)增加列、對(duì)單元格進(jìn)行合并,結(jié)合公司的jsp項(xiàng)目的已有功能完成單元格的增、刪、改操作。進(jìn)行需求分析整理后,經(jīng)過(guò)了一番查找,發(fā)現(xiàn)React版本的antd的表格組件功能很強(qiáng)大,可定制程度很高,可以助我完成這個(gè)業(yè)務(wù)需求的開(kāi)發(fā)。

由于要和jsp進(jìn)行交互,所以在實(shí)現(xiàn)過(guò)程中,遇到了一些難題踩了挺多坑,本文就跟大家分享下我從0到1實(shí)現(xiàn)這個(gè)需求的過(guò)程與思路,歡迎各位感興趣的開(kāi)發(fā)者閱讀本文。

環(huán)境搭建

因?yàn)楣镜捻?xiàng)目是基于jsp的,antd本想用Vue版本的,無(wú)奈它與jsp的一些語(yǔ)法沖突了跑不起來(lái),于是就嘗試了react版本的antd,它跑起來(lái)了沒(méi)有發(fā)現(xiàn)任何兼容性問(wèn)題,一切正常。給React點(diǎn)個(gè)贊??。

由于要與項(xiàng)目中已有的功能進(jìn)行交互,沒(méi)法用腳手架,我只能以cdn的方式引入react,如下所示,按順序引入react、axios、lodah以及antd所需要的文件。

  1. <script crossOrigin type="text/javascript" src="lib/react.production.min.js"></script> 
  2.    <script crossOrigin type="text/javascript" src="lib/react-dom.production.min.js"></script> 
  3.    <script src="lib/babel.min.js"></script> 
  4.    <script type="text/javascript" src="lib/moment.min.js"></script> 
  5.    <script src="lib/lodash.min.js"></script> 
  6.    <script type="text/javascript" src="lib/antd.min.js"></script> 
  7.    <script type="text/javascript" src="lib/axios.min.js"></script> 
  8.    <link rel="stylesheet" href="lib/antd.min.css"

 

 

 

 

 

 

 

 

上述用到的資源文件地址: react-antd-schedule/lib

我們需要把react相關(guān)代碼寫(xiě)在text/babel標(biāo)簽中,如下所示,我們打印antd和react看看是否有值。

  1. <script type="text/babel"
  2.     console.log("react"); 
  3.     console.log(React); 
  4.     console.log("antd"
  5.     console.log(antd); 
  6. </script> 

 

打開(kāi)瀏覽器控制臺(tái),出現(xiàn)下述信息,代表我們的環(huán)境已經(jīng)搭建成功。

image-20201119155715157

接下來(lái),我們寫(xiě)個(gè)HelloWord來(lái)測(cè)試下效果。

  1. <div id="root" style="width: 94%;overflow: hidden"></div> 
  2. <script type="text/babel"
  3.     // 自定義hook 
  4.     const App = () => { 
  5.         const onChange = (date, dateString) => { 
  6.             console.log(date, dateString); 
  7.         } 
  8.         return ( 
  9.             <div> 
  10.                 React+antd引入成功 
  11.                 <br /> 
  12.                 <antd.DatePicker onChange={onChange} /> 
  13.             </div> 
  14.         ); 
  15.     }; 
  16.     ReactDOM.render(<App />, document.getElementById("root")); 
  17. </script> 

 

 

 

 

執(zhí)行上述代碼,打開(kāi)瀏覽器如果看到下述效果,就證明我們的環(huán)境已經(jīng)搭好了。

image-20201119161505912

需要注意的是,CDN引入React和antd,他們是在全局暴露了一個(gè)對(duì)象,在使用它內(nèi)部的方法時(shí)就需要React.xx、antd.xx來(lái)訪(fǎng)問(wèn)了。

需求分析

當(dāng)我收到需求簡(jiǎn)述后,我對(duì)其進(jìn)行了整理:

  • 表格列要展示的內(nèi)容:日期、日程內(nèi)容(接口動(dòng)態(tài)返回),日程內(nèi)容列用戶(hù)可以自己手動(dòng)增加。
  • 表格行展示的內(nèi)容為每一天的數(shù)據(jù),每一天的數(shù)據(jù)分為:上午、下午、晚上三個(gè)時(shí)間段。
  • 日程內(nèi)容分為天日程和某個(gè)時(shí)間段的日程兩種狀態(tài),如果為天日程則需要進(jìn)行單元格合并。
  • 日程內(nèi)容列的每個(gè)單元格有5種狀態(tài),需要通過(guò)某種方式來(lái)區(qū)分,讓用戶(hù)一眼就能看出當(dāng)前日程處于什么狀態(tài)。
  • 日程內(nèi)容單元格的內(nèi)容如果為空時(shí),需要將單元格進(jìn)行合并,顯示一個(gè)增加圖標(biāo),點(diǎn)擊增加圖標(biāo)后,打開(kāi)系統(tǒng)的彈窗進(jìn)行增加操作,操作完成后,渲染內(nèi)容至剛才點(diǎn)擊的單元格。
  • 如果內(nèi)容單元格有內(nèi)容時(shí),根據(jù)不同的狀態(tài),打開(kāi)不同的彈窗進(jìn)行改、刪操作,操作完后,更新結(jié)果至對(duì)應(yīng)的單元格。

需求確定后,老板給我分了一個(gè)后端,跟后端溝通后開(kāi)發(fā)周期估了1周,我頁(yè)面估了2天的時(shí)間,剩下的3天與后端進(jìn)行數(shù)據(jù)對(duì)接。

2天后,我把頁(yè)面弄完了,表格需要的數(shù)據(jù)格式也定義好了,把數(shù)據(jù)格式發(fā)給后端后,他說(shuō)好,沒(méi)問(wèn)題。

因?yàn)闆](méi)有UI給設(shè)計(jì)圖,所以第一版,我就憑著自己的直覺(jué)來(lái)弄了,搞出來(lái)的東西蠻丑的,下圖就是我根據(jù)需求實(shí)現(xiàn)的頁(yè)面。

image-20201119172808318

然而,事情沒(méi)有預(yù)想中那么順利,我頁(yè)面做好后,到開(kāi)發(fā)周期的最后一天下午,后端把接口給我了,但返回的數(shù)據(jù)不是我預(yù)想的格式,我又進(jìn)行了二次處理,頁(yè)面渲染出來(lái)后,快到下班時(shí)間了,到了預(yù)估的開(kāi)發(fā)時(shí)間沒(méi)有完成需求,倒也能理解,畢竟后端那邊要處理的數(shù)據(jù)比較復(fù)雜。

本來(lái)預(yù)估了一周的開(kāi)發(fā)時(shí)間,后面需求的不斷增加、變更、UI設(shè)計(jì)效果圖,我的頁(yè)面代碼也從一開(kāi)始的100多行累加到現(xiàn)在的1000多行,這一套折騰下來(lái),直到需求開(kāi)發(fā)完成交給測(cè)試,花了20多天的時(shí)間。

需求實(shí)現(xiàn)

接下來(lái),就跟大家分享下在實(shí)現(xiàn)這個(gè)需求時(shí),遇到的難點(diǎn)、踩到的一些坑以及我的解決方案。

最后實(shí)現(xiàn)的效果如下所示,實(shí)現(xiàn)代碼請(qǐng)移步:react-antd-schedule/index.html

image-20201119175256753

動(dòng)態(tài)增加列

這個(gè)日程表用戶(hù)可以通過(guò)點(diǎn)增加圖標(biāo)來(lái)增加一列日程,此時(shí)我們就需要往表格頭部增加一列數(shù)據(jù),一開(kāi)始我覺(jué)得只要往antd的columns和dataSource中添加一條數(shù)據(jù)就行了,如下所示:

  1. const App = () => { 
  2.         const [columns, setColumns] = React.useState([]); 
  3.         const [optRecords, setOptRecords] = React.useState([]); 
  4.            //增加按鈕函數(shù) 
  5.         const btnClick = (e) => { 
  6.             index++; 
  7.             let columnsObj = { 
  8.                 dataIndex: 'rcnr' + (index), 
  9.                 title: '日程內(nèi)容' + index
  10.                 align: 'center'
  11.                 onCell: tdSet, 
  12.                 render: rctd_render, 
  13.             } 
  14.             // 表格列新增一列 
  15.             columns.push(columnsObj) 
  16.             setColumns(columns); 
  17.             // 處理表格數(shù)據(jù) 
  18.             for (let i = 0; i < optRecords.length; i++) { 
  19.                 let key = "rcnr"+index
  20.                 // 表格數(shù)據(jù)新增一條 
  21.                 optRecords[i][key] = {text:"", code:"0"
  22.             } 
  23.             setOptRecords(optRecords); 
  24.         } 
  25.  } 

當(dāng)我在瀏覽器執(zhí)行看效果時(shí),發(fā)現(xiàn)沒(méi)有生效,于是我下意識(shí)的打開(kāi)了瀏覽器控制臺(tái)看看是不是報(bào)錯(cuò)了,啪的一下,很快啊~新增加的那一列被渲染上去了,我大E了啊,antd不講武德啊。

于是,我多試了幾次,發(fā)現(xiàn)還是不渲染,打開(kāi)控制臺(tái)后就奇跡般的渲染上去了,有點(diǎn)摸不著頭腦,就求助了下網(wǎng)友,我才恍然大悟,原來(lái)是antd沒(méi)有監(jiān)聽(tīng)到引用地址的改變,得到了下述解決方案,用一個(gè)函數(shù)去處理它,讓antd監(jiān)聽(tīng)到引用地址改變,它才會(huì)將數(shù)據(jù)進(jìn)行渲染。

  1. const App = () => { 
  2.        const [optRecords, setOptRecords] = React.useState([]); 
  3.        const [columns, setColumns] = React.useState([]); 
  4.           //增加按鈕函數(shù) 
  5.        const btnClick = (e) => { 
  6.            if (tableLoadingStatus) { 
  7.                alert("表格數(shù)據(jù)尚未加載完成"); 
  8.                return false
  9.            } 
  10.            columnsIndex++; 
  11.            let columnsObj = { 
  12.                dataIndex: "rcnr" + (columnsIndex), 
  13.                title: "日程內(nèi)容" + columnsIndex, 
  14.                align: "left"
  15.                className: "rcnrfontSet"
  16.                width: 189.5, 
  17.                onCell: tdSet, 
  18.                render: rctd_render 
  19.            }; 
  20.            // 表格列新增一列 
  21.            setColumns((arr => [...arr, columnsObj])); 
  22.            // 處理表格數(shù)據(jù) 
  23.            setOptRecords((arr) => arr.map((item) => { 
  24.                return { ...item, ["rcnr" + columnsIndex]: { wz: columnsIndex - 1 } }; 
  25.            })); 
  26.             
  27.        }; 

表格列補(bǔ)齊

在后端返回的數(shù)據(jù)中,如果有不存在的日程,直接連字段都沒(méi)返回,這就造成了antd在渲染的時(shí)候列與表格數(shù)據(jù)不對(duì)應(yīng)而引發(fā)的武發(fā)渲染的問(wèn)題,于是我只能把所有數(shù)據(jù)遍歷一遍,求出最大列長(zhǎng)度,然后將列少的數(shù)據(jù)進(jìn)行補(bǔ)全,由于添加數(shù)據(jù)時(shí)接口需要傳當(dāng)前點(diǎn)擊的是哪一列,剛才補(bǔ)全的數(shù)據(jù)中是不包含wz字段的,因此我們需要再遍歷一次數(shù)據(jù),把wz字段加上去,代碼如下:

  1. // 表格數(shù)據(jù)渲染函數(shù) 
  2.         const tableDataRendering = function(res) { 
  3.           // 獲取最大子節(jié)點(diǎn)的key數(shù)量 
  4.             let maxChildLength = Object.keys(defaultData[0].children[0]).length; 
  5.             for (let i = 0; i < defaultData.length; i++) { 
  6.                 for (let j = 0; j < defaultData[i].children.length; j++) { 
  7.                     const currentObjLength = Object.keys(defaultData[i].children[j]).length; 
  8.                     if (currentObjLength > maxChildLength) { 
  9.                         maxChildLength = currentObjLength; 
  10.                     } 
  11.                 } 
  12.             } 
  13.  
  14.             // 補(bǔ)齊缺少的節(jié)點(diǎn) 
  15.             for (let i = 0; i < defaultData.length; i++) { 
  16.                 for (let j = 0; j < defaultData[i].children.length; j++) { 
  17.                     const currentObjLength = Object.keys(defaultData[i].children[j]).length; 
  18.                     // 當(dāng)前節(jié)點(diǎn)的長(zhǎng)度小于第一個(gè)子節(jié)點(diǎn)的長(zhǎng)度就補(bǔ)齊 
  19.                     for (let k = currentObjLength; k < maxChildLength; k++) { 
  20.                         defaultData[i].children[j]["rcnr" + k] = {}; 
  21.                     } 
  22.                 } 
  23.             } 
  24.  
  25.             // 如果存在空對(duì)象添加位置字段 
  26.             for (let i = 0; i < defaultData.length; i++) { 
  27.                 for (let j = 0; j < defaultData[i].children.length; j++) { 
  28.                     // 獲取每天的時(shí)間段對(duì)象 
  29.                     const item = defaultData[i].children[j]; 
  30.                     // 獲取所有的key 
  31.                     const keys = Object.keys(item); 
  32.                     // 提取所有的日程字段 
  33.                     for (let k = 1; k < keys.length; k++) { 
  34.                         // 日程為空添加wz字段 
  35.                         if (Object.keys(item[keys[k]]).length <= 1) { 
  36.                             defaultData[i].children[j][keys[k]].wz = k - 1; 
  37.                         } 
  38.                     } 
  39.                 } 
  40.             } 
  41.         } 

監(jiān)聽(tīng)子窗口關(guān)閉

但點(diǎn)擊單元格做完對(duì)應(yīng)的操作后,彈窗關(guān)閉,此時(shí)我們需要在當(dāng)前頁(yè)面監(jiān)聽(tīng)到子窗口關(guān)閉,然后向后臺(tái)請(qǐng)求接口重新獲取數(shù)據(jù)渲染頁(yè)面,在打開(kāi)的彈窗中提供了一個(gè)方法,可以調(diào)用父頁(yè)面的方法,但是這個(gè)方法必須寫(xiě)在hooks外面他才能獲取到。

此時(shí),問(wèn)題就產(chǎn)生了,如果寫(xiě)在hooks外面,那么就無(wú)法拿到antd表格內(nèi)部的數(shù)據(jù)做到頁(yè)面重新渲染,經(jīng)過(guò)一番思考后,想到了可以Proxy來(lái)實(shí)現(xiàn),當(dāng)被代理的對(duì)象發(fā)生改變時(shí),就觸發(fā)hooks里的代理函數(shù),實(shí)現(xiàn)代碼如下:

  1. <script type="text/babel"
  2.       // 聲明代理變量 
  3.     let pageStateEngineer; 
  4.     // 需要進(jìn)行代理的對(duì)象 
  5.     let pageState = { status: false }; 
  6.     // 監(jiān)聽(tīng)子頁(yè)面關(guān)閉,彈窗頁(yè)面在關(guān)閉時(shí)可調(diào)用這個(gè)方法,觸發(fā)頁(yè)面刷新 
  7.     const getSubpageData = (status) => { 
  8.         console.log("子頁(yè)面關(guān)閉"); 
  9.         pageStateEngineer.status = true
  10.     }; 
  11.     const App = () => { 
  12.         // 代理處理函數(shù) 
  13.         const pageStateHandler = { 
  14.             setfunction(recObj, key, value) { 
  15.                 // 表格狀態(tài)改為正在加載 
  16.                 setTableLoadingStatus(true); 
  17.                 // 重新請(qǐng)求接口,獲取最新數(shù)據(jù) 
  18.                 axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  19.                 }).then(function(res) { 
  20.                     // 數(shù)據(jù)請(qǐng)求成功,改變表格加載層狀態(tài) 
  21.                     setTableLoadingStatus(false); 
  22.                     if (res.status === 200) { 
  23.                         // 執(zhí)行表格數(shù)據(jù)渲染函數(shù) 
  24.                         tableDataRendering(res); 
  25.                     } else { 
  26.                         alert("服務(wù)器錯(cuò)誤"); 
  27.                     } 
  28.                 }); 
  29.                 // 修改對(duì)象屬性 
  30.                 recObj[key] = value; 
  31.                 return true
  32.             } 
  33.         }; 
  34.          
  35.         // 第一次渲染時(shí),在借口調(diào)用成功后創(chuàng)建proxy 
  36.         React.useEffect(() => { 
  37.             // 調(diào)用接口獲取表格數(shù)據(jù) 
  38.             axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  39.                 ls: 0, 
  40.                 ts: 0 
  41.             }).then(function(res) { 
  42.                 //創(chuàng)建代理,監(jiān)聽(tīng)pageState對(duì)象改變,pageStateHandler處理變更 
  43.                 pageStateEngineer = new Proxy(pageState, pageStateHandler); 
  44.             }) 
  45.         } 
  46.     } 
  47. </script> 

 

重新渲染表格

用戶(hù)在使用日程表時(shí),他會(huì)執(zhí)行刪除某個(gè)日程,此時(shí)表格渲染函數(shù)就要從columns和dataSource中各刪除一條數(shù)據(jù)了,一開(kāi)始我是直接覆蓋其數(shù)據(jù),這樣做引用地址沒(méi)變,就引發(fā)了動(dòng)態(tài)增加列的那個(gè)bug,antd監(jiān)聽(tīng)不到引用地址改變沒(méi)有刷新頁(yè)面。但是我又不知道用戶(hù)具體刪了哪條數(shù)據(jù),不好自己寫(xiě)函數(shù)去處理。

經(jīng)過(guò)一番求助后,得到了三個(gè)解決方案:

  • 使用immer來(lái)解決這個(gè)問(wèn)題,經(jīng)過(guò)折騰后還是沒(méi)實(shí)現(xiàn),他返回的數(shù)組是只讀的,antd無(wú)法對(duì)數(shù)據(jù)進(jìn)行操作,故放棄。
  • 使用use-immer來(lái)替代React的useState來(lái)解決這個(gè)問(wèn)題,這個(gè)就比較坑爹了,官方提供了umd的js庫(kù),但是通過(guò)cdn引入進(jìn)來(lái)后,我硬是沒(méi)找到它暴露出來(lái)的對(duì)象是哪個(gè),沒(méi)法用,故放棄。
  • 使用lodash的cloneDeep方法進(jìn)行深拷貝讓其引用地址改變,這樣antd就能監(jiān)聽(tīng)到數(shù)據(jù)改變,從而觸發(fā)頁(yè)面刷新。

三個(gè)解決方案,經(jīng)過(guò)驗(yàn)證后,只有第三個(gè)是可行的,于是我采取了它,實(shí)現(xiàn)代碼如下:

  1. const App = () => { 
  2.         // 表格列格式定義 
  3.         const defaultColumns = [ 
  4.             { 
  5.                 dataIndex: "rq"
  6.                 title: "日期"
  7.                 align: "center"
  8.                 fixed: "left"
  9.                 colSpan: 2, 
  10.                 width: 140.5, 
  11.                 className: "rqfontSet"
  12.                 onCell: dateHandle, 
  13.                 render: (value, item, index) => {} 
  14.             }, 
  15.             { 
  16.                 dataIndex: "sjd"
  17.                 title: "時(shí)間段"
  18.                 width: 70, 
  19.                 colSpan: 0, 
  20.                 fixed: "left"
  21.                 align: "center"
  22.                 className: "sjdfontSet"
  23.                 render: (value, item, index) => { 
  24.                     let v1 = value.charAt(0); 
  25.                     let v2 = value.charAt(1); 
  26.                     return <div>{v1}<br />{v2}</div>; 
  27.                 } 
  28.             } 
  29.         ]; 
  30.  
  31.         // 表格數(shù)據(jù)渲染函數(shù) 
  32.         const tableDataRendering = function(res) { 
  33.           // 根據(jù)日程列字段數(shù)據(jù)賦值表格列的日程字段,rcList中包含sjd所以需要1開(kāi)始 
  34.             for (let i = 1; i < rcList.length; i++) { 
  35.                 let rcnr = { 
  36.                     dataIndex: rcList[i], 
  37.                     title: "日程內(nèi)容" + i, 
  38.                     align: "left"
  39.                     width: 189.5, 
  40.                     className: "rcnrfontSet"
  41.                     onCell: tdSet, 
  42.                     render: rctd_render 
  43.                 }; 
  44.                 defaultColumns.push(rcnr); 
  45.             } 
  46.  
  47.             // 渲染表格數(shù)據(jù) 
  48.             handleData(defaultData); 
  49.             // 渲染表格列,使用cloneDeep進(jìn)行深拷貝,觸發(fā)useState的更新 
  50.             setColumns(_.cloneDeep(defaultColumns)); 
  51.         } 
  52.      // 計(jì)算要合并的列數(shù) 
  53.         const handleData = (data) => { 
  54.             if (data == null) { 
  55.                 data = defaultData; 
  56.             } 
  57.             let newArr = []; 
  58.             data.map(item => { 
  59.                 if (item.children) { 
  60.                     item.children.forEach((subItem, i) => { 
  61.                         let obj = { ...item }; 
  62.                         Object.assign(obj, subItem); 
  63.                         delete obj.children; 
  64.                         obj.rowLength = item.children.length; 
  65.                         newArr.push(obj); 
  66.                     }); 
  67.                 } 
  68.             }); 
  69.             // console.log("處理好的表格數(shù)據(jù)"); 
  70.             // console.log(newArr); 
  71.             // 將處理好的數(shù)據(jù)放入optRecords,使用cloneDeep進(jìn)行深拷貝,觸發(fā)useState的更新 
  72.             setOptRecords(_.cloneDeep(newArr)); 
  73.         }; 
  74.   } 

還有一種解決方案是使用JSON.parse進(jìn)行深拷貝,但是這種深拷貝有個(gè)問(wèn)題:但json數(shù)據(jù)中有函數(shù)時(shí),里面的函數(shù)會(huì)失效沒(méi)法執(zhí)行,由于我需要自定義antd的表格,在json數(shù)據(jù)中包含了函數(shù),因此我不能使用這個(gè)方法。

觸頂/觸底加載數(shù)據(jù)

由于業(yè)務(wù)需要,不能使用antd的分頁(yè)功能,需要實(shí)現(xiàn)觸頂向前加載30條數(shù)據(jù),觸底向后加載30條數(shù)據(jù)??偣仓荒芗虞d3個(gè)月的數(shù)據(jù)。

實(shí)現(xiàn)代碼如下:

 

這里需要比較坑的地方就是如果觸頂/觸底時(shí),拖動(dòng)橫向滾動(dòng)也會(huì)觸發(fā)滾動(dòng)監(jiān)聽(tīng),因此我們需要排除橫向滾動(dòng)事件。

  1. <script type="text/babel"
  2.     // 觸頂數(shù)據(jù)起始條數(shù) 
  3.     let dataToppingStartNum = 0; 
  4.     // 觸底數(shù)據(jù)起始條數(shù) 
  5.     let dataBottomOutStartNum = 30; 
  6.     // 橫向/垂直滾動(dòng)條起始位置 
  7.     let levelPosition; 
  8.     let verticalPosition; 
  9.     // 觸底/觸頂次數(shù) 
  10.     let topFrequency = 0; 
  11.     let bottomFrequency = 0; 
  12.     const App = () => { 
  13.         // 橫向滾動(dòng)條位置 
  14.         levelPosition = document.querySelector(".ant-table-body").scrollLeft; 
  15.         // 縱向滾動(dòng)條位置 
  16.         verticalPosition = document.querySelector(".ant-table-body").scrollTop; 
  17.         // 獲取表格容器 
  18.         let antdTable = document.querySelector(".ant-table-body"); 
  19.         //頁(yè)面滾動(dòng)監(jiān)聽(tīng) 
  20.         antdTable.onscroll = function() { 
  21.             // 觸底向后加載數(shù)據(jù) 
  22.             if (antdTable.scrollTop + antdTable.clientHeight >= antdTable.scrollHeight) { 
  23.                 // 判斷是否橫向滾動(dòng) 
  24.                 if (antdTable.scrollLeft !== levelPosition) { 
  25.                     // 更新位置 
  26.                     levelPosition = antdTable.scrollLeft; 
  27.                     return false
  28.                 } 
  29.                 // 第一次觸底不觸發(fā)數(shù)據(jù)加載 
  30.                 if (bottomFrequency === 0) { 
  31.                     bottomFrequency++; 
  32.                     return false
  33.                 } 
  34.                 if (bottomFrequency > 0) { 
  35.                     bottomFrequency = 0; 
  36.                 } 
  37.                 dataBottomOutStartNum += 30; 
  38.                 // 判斷已加載的數(shù)據(jù) 
  39.                 if (dataBottomOutStartNum > 90) { 
  40.                     alert("最多只能向后加載90天的數(shù)據(jù)"); 
  41.                     return false
  42.                 } 
  43.                 // 保留向上滑動(dòng)的天數(shù) 
  44.                 let bottomTS = 0; 
  45.                 // 頁(yè)面第一次向上滑動(dòng),修改位置 
  46.                 if (dataToppingStartNum !== 0) { 
  47.                     bottomTS = -30; 
  48.                 } 
  49.                 setTableLoadingStatus(true); 
  50.                 axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  51.                     ts: bottomTS, 
  52.                     ls: dataBottomOutStartNum 
  53.                 }).then(function(res) { 
  54.                     // 數(shù)據(jù)請(qǐng)求成功,改變表格加載層狀態(tài) 
  55.                     setTableLoadingStatus(false); 
  56.                     if (res.status === 200) { 
  57.                         // 執(zhí)行表格數(shù)據(jù)渲染函數(shù) 
  58.                         tableDataRendering(res); 
  59.                     } else { 
  60.                         alert("服務(wù)器錯(cuò)誤"); 
  61.                     } 
  62.                 }); 
  63.             } 
  64.  
  65.             // 觸頂向前加載數(shù)據(jù) 
  66.             if (antdTable.scrollTop === 0) { 
  67.                 // 判斷是否橫向滾動(dòng) 
  68.                 if (antdTable.scrollLeft !== levelPosition) { 
  69.                     // 更新位置 
  70.                     levelPosition = antdTable.scrollLeft; 
  71.                     return false
  72.                 } 
  73.                 // 第一次觸頂不觸發(fā)數(shù)據(jù)加載 
  74.                 if (topFrequency === 0) { 
  75.                     topFrequency++; 
  76.                     return false
  77.                 } 
  78.                 if (topFrequency > 0) { 
  79.                     topFrequency = 0; 
  80.                 } 
  81.                 dataBottomOutStartNum += 30; 
  82.                 if (dataBottomOutStartNum > 90) { 
  83.                     alert("最多只能向前加載90天的數(shù)據(jù)"); 
  84.                     return false
  85.                 } 
  86.                 dataToppingStartNum -= 30; 
  87.                 setTableLoadingStatus(true); 
  88.                 axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  89.                     ts: dataToppingStartNum, 
  90.                     ls: dataBottomOutStartNum 
  91.                 }).then(function(res) { 
  92.                     // 數(shù)據(jù)請(qǐng)求成功,改變表格加載層狀態(tài) 
  93.                     setTableLoadingStatus(false); 
  94.                     if (res.status === 200) { 
  95.                         // 執(zhí)行表格數(shù)據(jù)渲染函數(shù) 
  96.                         tableDataRendering(res); 
  97.                     } else { 
  98.                         alert("服務(wù)器錯(cuò)誤"); 
  99.                     } 
  100.                 }); 
  101.             } 
  102.         } 
  103.     } 
  104. </script> 

這里需要比較坑的地方就是如果觸頂/觸底時(shí),拖動(dòng)橫向滾動(dòng)也會(huì)觸發(fā)滾動(dòng)監(jiān)聽(tīng),因此我們需要排除橫向滾動(dòng)事件。

責(zé)任編輯:武曉燕 來(lái)源: 神奇的程序員k
相關(guān)推薦

2011-03-17 13:09:45

Ubuntu 11.1

2013-05-03 09:27:36

Ubuntu 13.1

2009-12-16 10:41:47

Android日程表

2009-09-29 13:32:40

Ubuntu 9.10Linux操作系統(tǒng)發(fā)布日程表

2013-09-09 15:38:13

Fedora 20Fedora操作系統(tǒng)

2009-03-05 08:30:57

LinuxUbuntu日程表

2009-03-23 07:36:43

Ubuntu 9.10win7正式版

2021-03-21 20:23:07

樹(shù)莓派Linux

2017-03-16 14:01:00

2011-06-02 09:58:09

CentOS 6.0

2015-10-29 11:36:45

Google技術(shù)經(jīng)理程序員

2022-09-22 12:38:46

antd form組件代碼

2022-07-06 08:29:12

antdInput 組件

2010-04-07 11:44:40

Ubuntu 10.1

2025-03-24 00:00:00

2009-12-21 17:53:45

Fedora Core

2015-05-11 17:21:33

Google IO2015

2021-05-12 09:07:09

Java數(shù)據(jù)結(jié)構(gòu)算法

2011-06-16 09:25:17

Firefox 5.0

2009-12-15 14:05:42

Fedora Core
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)