antd 中對樹形表格中二級元素進行篩選過濾


今天做了一個 antd 的表格,該表格是個樹形表格,也就是一行中還有 children 元素作為子行。

如圖所示:

需求要求對二級元素即 children 元素進行篩選,但是 antd 自身的 onFilter 並不能篩選 children。。。我也在網上查詢了相關信息,並沒查到有效的解決方案,相對有效的就是篩選的時候自己對 dataSource 進行過濾,但是這就會導致復雜度的增加。比如此方案我們就需要將后端返回的數據克隆一份,然后對此克隆數據進行過濾等操作。而且我這需求中還需要對后端返回的數據進行編輯,編輯的文件也是備份文件,那么編輯后還要將備份文件和源文件同步等操作。這就很蛋疼了。。。

不過最后還是通過一個比較簡單的方法解決了此問題。
在對 dataSource 不進行刪除就實現過濾功能,首先想到的就是如何能隱藏某一行,比如可以給 dataSource 中的每行添加一個 hidden 屬性,通過判斷此屬性來決定這行是否顯示。
在查詢 antd 的文檔后,終於發現了此方法,這樣的功能可能比較少見,網上也沒有能直接搜到的結果,其實就是通過設置 onRow 屬性:

<Table
    columns={departmentColumns}
    dataSource={dataSource}
    loading={loading}
    expandIconColumnIndex={1}
    pagination={false}
    onRow={record => {
        // 隱藏 hidden 為 true 的行
        if (record.hidden) {
            return {
                style: { display: 'none' }
            }
        }
    }}
/>

這個屬性我之前也沒用到過,而且文檔中也只舉例了幾個事件綁定操作,我也是通過觀察猜測實驗后得出的方法:)
既然能隱藏某一行那就好說了,只需在進行篩選的時候先將所有元素先顯示即 hidden: true,再在 onFilter 里對被過濾的元素隱藏即可。

    const [filterValue, setFilterValue] = useState({ first: '', firstScore: '', second: '', secondScore: '' });
    const onFilterChange = (type, v) => {
        // 每次過濾的時候,都先將所有行的 hidden 改為 false
        // 這里將所有改為 false,不用擔心其它某列進行了篩選,把為 true 的給改到了。因為 antd 的 columns 中的 onFilter 會在每次重新渲染的時候都執行一遍
        dataSource.forEach(item => {
            item.hidden = false;
            item.children.forEach(child => {
                child.hidden = false;
            });
        })

        setFilterValue({
            ...filterValue,
            [type]: v
        });
    }
        {
            title: '得分【狀態】',
            dataIndex: 'secondScore',
            filterDropdown: <FilterRadio
                options={secondScoreLevelFilter}
                value={filterValue.secondScore}
                onChange={v => {
                    onFilterChange('secondScore', v);
                }}
            />,
            filteredValue: filterValue.secondScore ? [filterValue.secondScore] : null,
            onFilter: (v, record) => {
                // 二級過濾,只能通過給行添加 hidden: true,然后通過 Table 的 onRow 進行過濾
                record.children.forEach(child => {
                    child.hidden = child.hidden || child.scoreLvl !== v;  // 需要先判斷下如果當前行 hidden 為 true 就直接返回。hidden 為 true 說明其它列的篩選將此行過濾了。
                });
                return record.children.find(item => item.scoreLvl === v);
            },
            render(v, record) {
                return record.index ? null :`${getValue(record.score)}【${getValue(record.scoreLvl)}】`;
            }
        },

希望這篇文章能幫到遇到類似需求的同行~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM