简体   繁体   English

Ag-grid 可编辑网格动态添加新行

[英]Ag-grid editable grid adding new row dynamically

I have an editable AgGrid in my functional component as below.我的功能组件中有一个可编辑的 AgGrid,如下所示。 On the last column, I have buttons to Add/Remove rows.在最后一列,我有添加/删除行的按钮。 Now I want the Add row to be displayed only for the last row.现在我希望只为最后一行显示添加行。 I am using cellRenderer for the last column.我在最后一列使用 cellRenderer。

With the below change, I get the Add button for the last row (ie on 2nd row in my case) on initial render.通过以下更改,我在初始渲染时获得了最后一行(即在我的情况下为第二行)的添加按钮。 But if I click on Add for this 2nd row, while I get the Add button for the new 3rd row, but it does not get removed for the 2nd row.但是,如果我单击第二行的添加,而我得到新的第三行的添加按钮,但它不会被第二行删除。 not sure if I am implementing this in the wrong way.不确定我是否以错误的方式实现了这一点。

const MyCmp = (props) => {

    const getData = () => {
        return [{
            id: 0,
            firstName: 'F1',
            lastName: 'L1'
        }, {
            id: 1,
            firstName: 'F2',
            lastName: 'L2',
        }];
    }

    const [myCols, setMyCols] = useState(null);
    const [gridData, setGridData] = useState(getData());

    const [gridApi, setGridApi] = useState('');  

    let cellRules = {
        'rag-red': params => {
            if (params.data.lastName === 'INVALID_VAL') {
                return true;
            }
        }
    };

    const handleGridReady = (params) => {
        setGridApi(params.api);
        setMyCols([{
            headerName: 'F Name',
            field: 'firstName',
            editable: true
        }, {
            headerName: 'L Name',
            field: 'lastName',
            cellClassRules: cellRules,
            editable: true
        }, {
            headerName: '',
            field: 'buttonCol',
            cellRenderer: 'customColRenderer',
            cellRendererParams: {
                addItems: addItems
            }
        }]
        );
    };

    const createNewRowData = () => {
        const newData = {
            id: newCount,
            firstName: '',
            lastName: ''
        };
        newCount++;
        return newData;
    }

    let newCount = getData().length;

    const addItems = (addIndex, props) => {
        const newItems = [createNewRowData()];
        const res = props.api.applyTransaction({
            add: newItems,
            addIndex: addIndex,
        });

        setGridData(...gridData, res.add[0].data); // IS THIS CORRECT ?

        if (props.api.getDisplayedRowCount() > props.api.paginationGetPageSize()) {
            props.api.paginationGoToPage(parseInt((props.api.getDisplayedRowCount() / props.api.paginationGetPageSize())) + 1);
        }
    }

    const onCellClicked = (e) => {
    }

    const frameworkComponents = () => {
        return {customColRenderer: customColRenderer}
    }

    return (
        <>
            <MyAgGrid
                    id="myGrid"
                    columnDefs={myCols}
                    rowData={gridData}
                    frameworkComponents={{customColRenderer: customColRenderer}}
                    {...props}
                />
        </>
    )
}

My customColRenderer is as below;我的 customColRenderer 如下;

export default (props) => {
        let isLastRow = (props.rowIndex === (props.api.getDisplayedRowCount() -1)) ? true: false;
        const addItems = (addIndex) => {
            props.addItems(addIndex, props);
        }

        return (
            <span>
                {isLastRow ? <button onClick={() => addItems()}>Add</button> : null}
                <span><button onClick={() => props.api.applyTransaction({remove: props.api.getSelectedRows()})}>Remove</button>
            </span>
        );
};

Within the AgGrid React internals a transaction is generated automatically when your rowData is updated, as such you can choose to apply the transaction either through the api, or by updating your state - you shouldn't need to do both (as you're currently doing).在 AgGrid React 内部,当您的 rowData 更新时会自动生成一个事务,因此您可以选择通过 api 或通过更新您的状态来应用事务 - 您不需要同时执行这两个操作(因为您目前正在做)。 Generally with React I'd suggest updating the state to keep your state true to the data displayed in the grid, however that can depend on use case.通常使用 React,我建议更新状态以使您的状态与网格中显示的数据保持一致,但这可能取决于用例。

As for the further issue of your cell not updating - that'll be due to the fact AgGrid has detected no change in the 'value' of the cell, as it attempts to reduce the amount of unnecessary cell rendering done.至于您的单元格未更新的进一步问题 - 这是因为 AgGrid 检测到单元格的“值”没有变化,因为它试图减少不必要的单元格渲染量。

You could attempt to call:您可以尝试致电:

api.refreshCells({ force: true });

After your api call applying the transaction (I'm not sure where this would need to happen using the setState approach).在应用事务的 api 调用之后(我不确定使用 setState 方法需要在哪里发生)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM