5 votes

AG-Grid React, difficulté à faire en sorte que le rendu des cellules personnalisées soit mis à jour lorsque les données changent. Les composants de fonction se comportent différemment des composants d

J'utilise AG-Grid dans une application react, et dans plusieurs cas, je veux qu'un cellRenderer se mette à jour lorsque les données de la grille changent. Dans les deux cas suivants, le cellRenderer se charge correctement au départ, mais ne se met pas à jour lorsque les données changent :

  1. Un utilisateur édite une cellule modifiable et en change la valeur.
  2. Le serveur met à jour les données de la grille en redux

Regarde ça codesandbox

Dans cet exemple, j'ai recréé le premier cas d'utilisation avec une cellule modifiable, et j'ai utilisé un composant de classe et un composant de fonction. En utilisant onCellValueChanged avec params.api.refreshCells(), j'ai réussi à mettre à jour le composant de classe, mais pas le composant de fonction.

Première question : Comment faire en sorte que les composants de fonction react soient rendus avec de nouveaux props, de la même manière que le composant de classe dans l'exemple codesandbox ?

Deuxième question : Existe-t-il un meilleur moyen de mettre à jour un cellRenderer sans démonter et remonter chaque cellule de la colonne à chaque mise à jour des données ?

Merci d'avance pour votre aide et vos conseils !

...
    this.state = {
      columnDefs: [
        {
          headerName: "Editable Country",
          editable: true,
          field: "country",
          width: 200
        },
        {
          headerName: "Class Render",
          cellRendererFramework: GridCellClass,
          colId: "class-renderer",
          width: 200
        },
        {
          headerName: "Function Render",
          cellRendererFramework: GridCellFunction,
          colId: "function-renderer",
          width: 200
        }
      ],
      rowData: []
    };
  }

...

            <AgGridReact
              rowModelType="infinite"
              columnDefs={this.state.columnDefs}
              enableColResize={true}
              rowClassRules={{
                california: function(params) {
                  return params.data.country === "California";
                }
              }}
              onCellValueChanged={function(params) {
                return params.api.refreshCells({
                  force: true,
                  columns: ["class-renderer", "function-renderer"]
                });
              }}
              onGridReady={this.onGridReady.bind(this)}
              rowData={this.state.rowData}
            />
...

// This one updates!
import React, { Component } from "react";

class GridCellClass extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    const { data } = this.props;

    return (
      <div>
        {data.country === "California" ? "CALIFORNIA!!!" : "Not California"}
      </div>
    );
  }
}

export default GridCellClass;

// This one does not update.
import React from "react";

function GridCellFunction(props) {
  const { data } = props;

  return (
    <div>
      {data.country === "California" ? "CALIFORNIA!!!" : "Not California"}
    </div>
  );
}

export default GridCellFunction;

4voto

Pratik Bhat Points 1928

1. Fonction de rendu des cellules

Une fonction de rendu de cellule doit être utilisée lorsque vous n'avez pas d'exigences en matière de rafraîchissement, ce qui est mentionné dans la documentation de la grille d'agriculture.

Conformément à docs -

Utilisez la variante de fonction d'un moteur de rendu de cellules si vous n'avez pas de rafraîchissement ou de de nettoyage (c'est-à-dire que vous n'avez pas besoin de mettre en œuvre les fonctions de détruire).

C'est la raison pour laquelle votre fonction de rendu de cellules ne se rafraîchit pas.

Pour résoudre votre problème, vous pouvez faire ceci -

      onCellValueChanged={function(params) {
        if(params.column.getId() === 'country') {
          params.api.redrawRows();
        }
      }}

2. Composant de rendu de cellules

La raison pour laquelle votre GridCellClass travaille sur api.refreshCells() c'est parce que la grille gère les refresh() pour vous puisque vous n'avez pas mis en œuvre refresh() dans votre GridCellClass composant.

Cela signifie que votre composant sera détruit et recréé si les données sous-jacentes changent.

3. RefreshCells

Notez également que l'utilisation de api.refreshCells() ne fonctionnera pas tel quel car ag-grid utilise la détection de changement pour rafraîchir les cellules tout en déterminant quelles cellules rafraîchir et puisque essentiellement la valeur de vos 2 autres colonnes ne change pas mais en fait elles sont modifiées dans le cellRenderer lui-même.

Cependant, le texte ci-dessous fonctionne pour GridCellClass car vous désactivez la détection des changements en passant force:true ,

       params.api.refreshCells({
          force: true
        });

De docs-

La détection des changements sera utilisée pour réf ne sont pas synchronisées avec la valeur réelle. Si vous utilisez un cellRenderer avec une méthode de rafraîchissement, la méthode de rafraîchissement sera appelée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X