简体   繁体   English

AG-网格反应。 如何仅为叶节点附加自定义 cellRenderer,而不破坏内置的行分组功能

[英]AG-Grid React. How to attach a custom cellRenderer for leaf nodes only, without breaking the built-in row grouping feature

Simplified from this ag-grid example .这个 ag-grid 示例中简化。 See code comments.请参阅代码注释。 I can attach a custom cellRenderer for rowGroup rows.我可以为 rowGroup 行附加一个自定义 cellRenderer。 But all my attempts at a custom cellRenderer for leaf node rows have broken the row grouping functionality.但是我对叶节点行的自定义 cellRenderer 的所有尝试都破坏了行分组功能。 Seems we can differentiate leaf vs group nodes via existence of params.data.似乎我们可以通过 params.data 的存在来区分叶子节点和组节点。 If I put a cellRenderer in the autoGroupColumnDef, bad things happen: I lose all group row functionality.如果我将 cellRenderer 放在 autoGroupColumnDef 中,就会发生坏事:我失去了所有组行功能。 If I test for params.data in that cellRenderer, I don't know what to return if it's not a leaf node.如果我在那个 cellRenderer 中测试 params.data,如果它不是叶节点,我不知道要返回什么。 I've tried several angles on 'agGroupCellRenderer', none correct.我在“agGroupCellRenderer”上尝试了几个角度,都不正确。 Thank you.谢谢你。

'use strict';

import React, { useCallback, useMemo, useRef, useState } from 'react';
import { render } from 'react-dom';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-enterprise';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: '100%', height: '100%' }), []);
  const gridStyle = useMemo(() => ({ height: '100%', width: '100%' }), []);
  const [rowData, setRowData] = useState();
  const [columnDefs, setColumnDefs] = useState([
    { field: 'country', rowGroup: true, hide: true }
    /*  I've whittled things down to only 1-deep leaf rows, and the auto-generated group rows.
      { field: 'sport', rowGroup: true, hide: true },
      { field: 'gold', aggFunc: 'sum' },
      { field: 'silver', aggFunc: 'sum' },
      { field: 'bronze', aggFunc: 'sum' },
      { field: 'age', minWidth: 120, checkboxSelection: true, aggFunc: 'sum' },
      { field: 'year', maxWidth: 120 },
      { field: 'date', minWidth: 150 },
    */
  ]);
  const defaultColDef = useMemo(() => {
    return {
      flex: 1,
      minWidth: 100,
      // New: added cellRenderer. Seems to apply only to rowGroup rows
      cellRenderer: params => {
        return 'groupRow cellRenderer: ' + params.value;
      }
    };
  }, []);
  const autoGroupColumnDef = useMemo(() => {
    return {
      headerName: 'Athlete',
      field: 'athlete',
      minWidth: 250,
      cellRenderer: 'agGroupCellRenderer',
      cellRendererParams: {
        checkbox: true,
      },
    };
  }, []);

  // Now want to add a cellRenderer that applies ONLY to leaf nodes.
  // Seems we can differentiate leaf vs group nodes via existence of params.data.
  // If I put a cellRenderer in the above autoGroupColumnDef, bad things happen:
  // I lose all group row functionality. If I test for params.data in that cellRenderer, I don't know
  // what to return if it's not a leaf node. I've tried several angles on 'agGroupCellRenderer', none correct.

  const gridRef = useRef();
  const [gridApi, setGridApi] = useState(null);
  const onGridReady = useCallback((params) => {
    fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
      .then((resp) => resp.json())
      .then((data) => setRowData(data));
    // Added: grab a gridRef reference
    gridRef.current = document.querySelector('#theGrid');  
    // Added: grab the api instance
    setGridApi(params.api);
  }, []);

  return (
    <div style={containerStyle}>
      <div id="theGrid" style={gridStyle} className="ag-theme-alpine">
        <AgGridReact
          rowData={rowData}
          columnDefs={columnDefs}
          defaultColDef={defaultColDef}
          autoGroupColumnDef={autoGroupColumnDef}
          rowSelection={'multiple'}
          groupSelectsChildren={true}
          suppressRowClickSelection={true}
          suppressAggFuncInHeader={true}
          onGridReady={onGridReady}
        ></AgGridReact>
      </div>
    </div>
  );
};

render(<GridExample></GridExample>, document.querySelector('#root'));

Well, I was able to sidestep the issue, by employing an innerRenderer in the autoGroupColumnDef , which gets applied to all nodes, both group and leaf.好吧,我能够通过在autoGroupColumnDef中使用innerRenderer来回避这个问题,它适用于所有节点,包括组和叶。 Even so, would still like to know how to directly invoke the default 'agGroupCellRenderer' other than declaratively via cellRenderer: 'agGroupCellRenderer' (how to invoke it from a cellRendererSelector , for example).即便如此,仍然想知道如何直接调用默认的“agGroupCellRenderer”,而不是通过cellRenderer: 'agGroupCellRenderer' (例如,如何从cellRendererSelector调用它)。
Here's a corrected version with functional innerRenderer :这是具有功能innerRenderer的更正版本:

'use strict';

import React, { useCallback, useMemo, useRef, useState } from 'react';
import { render } from 'react-dom';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-enterprise';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: '100%', height: '100%' }), []);
  const gridStyle = useMemo(() => ({ height: '100%', width: '100%' }), []);
  const [rowData, setRowData] = useState();
  const [columnDefs, setColumnDefs] = useState([
    { field: 'country', rowGroup: true, hide: true }
    /*  I've whittled things down to only 1-deep leaf rows, and the auto-generated group rows.
      { field: 'sport', rowGroup: true, hide: true },
      { field: 'gold', aggFunc: 'sum' },
      { field: 'silver', aggFunc: 'sum' },
      { field: 'bronze', aggFunc: 'sum' },
      { field: 'age', minWidth: 120, checkboxSelection: true, aggFunc: 'sum' },
      { field: 'year', maxWidth: 120 },
      { field: 'date', minWidth: 150 },
    */
  ]);
  const defaultColDef = useMemo(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);
  const autoGroupColumnDef = useMemo(() => {
    return {
      headerName: 'Athlete',
      field: 'athlete',
      minWidth: 250,
      cellRenderer: 'agGroupCellRenderer',
      cellRendererParams: {
        checkbox: true,        
        // Declare the new innerRenderer:
        innerRenderer: SimpleCellRenderer,
      },
    };
  }, []);

  // Slight modification of Ag's example
  function SimpleCellRenderer (props) 
  { 
    return (
        <span
          style={{
            // This differentiates based on node level ('0' for group nodes, '1' for leaf nodes)
            backgroundColor: props.node.level ? 'coral' : 'lightgreen',
            padding: 2,
          }}
        >
          {props.value}
        </span>
    )
  };

  const gridRef = useRef();
  const [gridApi, setGridApi] = useState(null);
  const onGridReady = useCallback((params) => {
    fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
      .then((resp) => resp.json())
      .then((data) => setRowData(data));
    // Added: grab a gridRef reference
    gridRef.current = document.querySelector('#theGrid');  
    // Added: grab the api instance
    setGridApi(params.api);
  }, []);

  return (
    <div style={containerStyle}>
      <div id="theGrid" style={gridStyle} className="ag-theme-alpine">
        <AgGridReact
          rowData={rowData}
          columnDefs={columnDefs}
          defaultColDef={defaultColDef}
          autoGroupColumnDef={autoGroupColumnDef}
          rowSelection={'multiple'}
          groupSelectsChildren={true}
          suppressRowClickSelection={true}
          suppressAggFuncInHeader={true}
          onGridReady={onGridReady}
        ></AgGridReact>
      </div>
    </div>
  );
};

render(<GridExample></GridExample>, document.querySelector('#root'));

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

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