Visão geral e configuração do React Grid

    O componente Grade de Dados React é usado para exibir grandes volumes de dados. Grades modernas e mais complexas garantem uma experiência do usuário suave e trazem uma variedade de recursos para manipular dados tabulares. Há uma API intuitiva, temas, branding, filtragem, classificação, seleção de dados, filtragem no estilo Excel e muito mais.

    A Tabela de Dados/Grade de Dados Ignite UI for React é um componente de grade de React tabular que permite vincular e exibir rapidamente seus dados com pouca codificação ou configuração. Os recursos da grade de dados React em nossa caixa de ferramentas incluem filtragem, classificação, modelos, seleção de linhas, agrupamento de linhas, fixação de linhas, colunas móveis, virtualização, Master-Detail e muito mais.

    As tabelas React são otimizadas para velocidade e desempenho, com a capacidade de lidar com milhões de linhas e colunas e atualizações em tempo real em um instante, tornando o Ignite UI for React Data Grid o melhor Data Grid React do mercado.

    React Grade de Dados

    React Data Grid Example

    Neste exemplo de Ignite UI for React Grid, você pode ver como os usuários podem fazer filtragem básica e no estilo do Excel, classificação de dados em tempo real e usar resumos de grade, bem como modelos de célula. A demonstração também inclui um conjunto de paginação para exibir 10 itens por página.

    Getting Started with React Data Grid

    Dependencies

    Para começar com o React Data Grid, primeiro você precisa instalar osigniteui-react pacotes e.igniteui-react-grids

    npm install --save igniteui-react
    npm install --save igniteui-react-grids
    

    Você também precisa incluir a seguinte importação para usar a grade:

    import { IgrGrid } from "igniteui-react-grids";
    

    Os estilos correspondentes também devem ser referenciados. Você pode escolher a opção clara ou escura para um dos temas e, com base na configuração do seu projeto, importá-lo:

    import 'igniteui-react-grids/grids/themes/light/bootstrap.css'
    

    Para obter mais detalhes sobre como personalizar a aparência da grade, você pode dar uma olhada na seção de estilo.

    Usage

    Agora que temos os pacotes de grade importados, vamos começar com a configuração básica e vincular aos dados locais:

    <IgrGrid id="grid1" data={localData} autoGenerate={true}></IgrGrid>
    

    Aid propriedade é um valor de cadeia e é o identificador único da grade, que será gerado automaticamente se não for fornecido, enquantodata vincula a grade, neste caso, a dados locais.

    AautoGenerate propriedade orienta a grade a gerar automaticamente os componentes daIgrColumn grade com base nos campos da fonte de dados. Também tentará deduzir o tipo de dado apropriado para a coluna, se possível. Caso contrário, o desenvolvedor precisa definir explicitamente as colunas e o mapeamento para os campos da fonte de dados.

    Editable React Grid

    Cada operação para edição de grade inclui operações em lote, o que significa que a API oferece a opção de agrupar edições em uma única chamada de servidor, ou você pode executar operações de edição/atualização de grade conforme elas ocorrem com interações de grade. Juntamente com uma ótima experiência de desenvolvedor como uma grade editável com operações CRUD, a grade inclui navegação por teclado semelhante ao Excel. A navegação em grade padrão comum está incluída, além da opção de substituir qualquer opção de navegação para atender às necessidades de seus clientes. Uma grade editável com um ótimo esquema de navegação é fundamental para qualquer aplicativo moderno de linha de negócios, com a grade Ignite UI facilitamos.

    Seguindo este tópico, você aprenderá mais sobre o modelo de célula e o modelo de edição e edição de célula.

    Grid Column Configuration

    IgrColumné usado para definir a coleção de colunas da grade e para habilitar recursos por coluna, como ordenação e filtragem. Modelos de célula, cabeçalho e rodapé também estão disponíveis.

    Defining Columns

    Vamos desligar aautoGenerate propriedade e definir a coleção de colunas na marcação:

    <IgrGrid id="grid1" autoGenerate={false} allowFiltering={true} data={localData}>
        <IgrColumn field="Name" sortable={true}></igc-column>
        <IgrColumn field="AthleteNumber" header="Athlete number" filterable={false} sortable={true}></IgrColumn>
        <IgrColumn field="TrackProgress" header="Track progress" filterable={false}></IgrColumn>
    </IgrGrid>
    

    Modelo de cabeçalho

    O modelo de cabeçalho pode ser definido para modificar os cabeçalhos de coluna. Os snippets abaixo mostram como formatar o texto do cabeçalho em maiúsculas.

    function nameHeaderTemplate(ctx: IgrColumnTemplateContext) {
        return (
            <>
                {formatUppercase(ctx.column.field)}
            </>
        );
    }
    
    function formatUppercase(value: string) {
        return value.toUpperCase();
    }
    
    <IgrColumn field="Name" headerTemplate={nameHeaderTemplate}></IgrColumn>
    

    Template de Célula

    Quando o modelo de célula é definido, ele altera todas as células da coluna. O objeto de contexto fornecido no modelo consiste no valor da célula fornecido implicitamente e no próprio objeto de célula. Ele pode ser usado para definir um modelo onde o texto das células pode ser formatado, por exemplo, como maiúsculas e minúsculas.

    function formatTitleCase(value: string) {
        return value.toUpperCase();
    }
    
    function nameCellTemplate(ctx: IgrCellTemplateContext) {
        return (
            <>
                {formatTitleCase(ctx.implicit)}
            </>
        );
    }
    
    <IgrColumn field="Name" bodyTemplate={nameCellTemplate}></IgrColumn>
    

    No trecho acima, fazemos referência ao valor da célula implicitamente fornecido. Isso é suficiente se você só quiser apresentar alguns dados e talvez aplicar algum estilo personalizado ou transformações de pipe sobre o valor da célula. No entanto, ainda mais útil é pegar aCell instância em si, como mostrado abaixo:

    function nameCellTemplate(ctx: IgrCellTemplateContext) {
        return (
            <>
                <span tabIndex={0} onClick={() => deleteRow(ctx.cell.id.rowID)}>
                    {formatTitleCase(ctx.cell.value)}
                </span>
            </>
        );
    }
    
    function subscriptionCellTemplate(ctx: IgrCellTemplateContext) {
        if (ctx.cell.value) {
                return (
                    <>
                    <input type="checkbox" checked />
                    </>
                );
        } else {
                return (
                    <>
                    <input type="checkbox"/>
                    </>
                );
        }
    }
    
    function deleteRow(rowID: any) {
        grid.current.deleteRow(rowID);
    }
    
    function formatTitleCase(value: string) {
        return value.toUpperCase();
    }
    
    <IgrGrid id="grid" ref={grid} autoGenerate={false} data={data} primaryKey="Name">
        <IgrColumn field="Name" dataType="string" bodyTemplate={nameCellTemplate}></IgrColumn>
        <IgrColumn field="Subscription" dataType="boolean" bodyTemplate={subscriptionCellTemplate}></IgrColumn>
    </IgrGrid>
    

    Nota: A grade exibe um tratamento padrão para tipos de número, string, data e colunas booleanas. Por exemplo, a coluna será exibidacheck ou umclose ícone, em vez de verdadeiro/falso por padrão, para o tipo de coluna booleana.

    Quando implementado corretamente, o modelo de edição de células também garante que as célulasEditValue passarão corretamente pelo ciclo de eventos de edição em grade.

    Cell Editing Template

    A coluna também aceita um último modelo que será usado quando uma célula estiver em modo de edição. Assim como nos outros modelos de coluna, o objeto de contexto fornecido é novamente o valor da célula e o próprio objeto célula. Claro, para tornar o modelo de edição acessível aos usuários finais, é preciso definir aeditable propriedade da coluna como true.

    function priceCellTemplate(ctx: IgrCellTemplateContext) {
        return (
            <>
                <label>
                    Enter the new price tag
                </label>
                <input name="price" type="number" value={ctx.cell.value}
                    onChange={() => updateValue(ctx.cell.value)}/>
            </>
        );
    }
    
    function updateValue(value: number) {
      // Custom update code
    }
    
    <IgrColumn field="Price" dataType="number" editable={true} inlineEditorTemplate={priceCellTemplate}></IgrColumn>
    

    Certifique-se de verificar a APICell para se acostumar com as propriedades fornecidas que você pode usar nos seus templates.

    Column Template API

    Cada um dos modelos de coluna pode ser alterado programaticamente a qualquer momento através doIgrColumn próprio objeto. Por exemplo, no código abaixo, declaramos dois modelos para nossos dados de usuário. No nosso código TypeScript, obteremos referências aos próprios templates e, com base em alguma condição, renderizaremos o template apropriado para a coluna em nossa aplicação.

    <IgrGrid ref={grid}>
        {/* Column declarations */}
    </IgrGrid>
    
    function normalViewTemplate(ctx: IgrCellTemplateContext) {
        return (
            <>
                <div className="user-details">{ ctx.cell.value }</div>
                <UserDetailsComponent></UserDetailsComponent>
            </>
        );
    }
    
    function smallViewTemplate(ctx: IgrCellTemplateContext) {
        return (
            <>
                <div className="user-details-small">{ ctx.cell.value }</div>
            </>
        );
    }
    
    const column = grid.current.getColumnByName("User");
    // Return the appropriate template based on some condition.
    // For example saved user settings, viewport size, etc.
    column.bodyTemplate = smallViewTemplate;
    

    As propriedades das colunas também podem ser definidas no código noColumnInit evento emitido quando as colunas são inicializadas na grade.

    function initColumns(event: CustomEvent<IgrColumn>) {
        const column: IgrColumn = event.detail;
        if (column.field === 'ProductName') {
            column.sortable = true;
            column.editable = true;
        }
    }
    
    <IgrGrid onColumnInit={initColumns} />
    

    O código acima tornará a coluna ProductName classificável e editável e instanciará a interface do usuário dos recursos correspondentes (como entradas para edição etc.).

    Custom Display Format

    Há parâmetros opcionais para formatação:

    • Format- determina quais partes de data/hora são exibidas, como padrão'mediumDate', equivalente a 'MMM d, y'
    • Timezone- o desfasamento do fuso horário para datas. Por padrão, usa o fuso horário local do sistema do usuário final
    • DigitsInfo- objetos de representação decimal. Padrão para 1.0-3

    Para permitir a personalização do formato de exibição por esses parâmetros, apipeArgs entrada é exposta. Uma coluna respeitará apenas as propriedades correspondentes para seu tipo de dado, sepipeArgs for definido. Exemplo:

    const columnPipeArgs: IgrColumnPipeArgs = {
        format: "longDate",
        timezone: "UTC",
        digitsInfo: "1.2-2"
    };
    
    <IgrColumn field="OrderDate" dataType="date" pipeArgs={columnPipeArgs}></IgrColumn>
    

    AOrderDate coluna respeitará apenas asFormat propriedades eTimezone e respeitará.UnitPriceDigitsInfo

    Todos os tipos de dados de coluna disponíveis podem ser encontrados no tópico oficial Tipos de coluna.

    Grid Data Structure

    EleIgrGrid lida com dados planos e POJO aninhados (objetos Java comuns). A estrutura de dados específica para renderização está na forma:

    const OBJECT_ARRAY = [{
            ObjectKey1: value1,
            ObjectKey2: value2,
            // ...
            ObjectKeyN: valueN
        },
        // ...
      }];
    
    const POJO = [{
            ObjectKey1: value1,
            ObjectKey2: value2,
            // ...
            ObjectKeyN: {
              ObjectKeyN1: value1,
              ObjectKeyN2: value2,
              // ...
              ObjectKeyNM: valueNM,
            }
        },
        // ...
      }];
    

    AVISO:​ ​Os valores de chave não devem conter matrizes.

    Se você usarautoGenerate​ ​colunas, as chaves de dados devem ser idênticas.

    Grid Data Binding

    Nosso React Data Grid oferece opções de vinculação de dados incomparáveis e é otimizado para atualizações em tempo real e rolagem suave. Com renderização de baixa latência, a grade garante que qualquer alteração na interface do usuário seja exibida em um instante, incluindo dados de transmissão ao vivo, grandes conjuntos de dados e muito mais.

    Antes de prosseguir com o React Data Grid, queremos alterar a grade para se vincular ao serviço de dados remoto, que é o cenário comum em aplicativos de grande escala.

    Você pode fazer isso pegando os dados de uma determinada URL que recebe uma resposta JSON e atribuindo-os à propriedade dadata grade usada como fonte de dados da grade:

    <IgrGrid ref={grid} data={data}></IgrGrid>
    
    const [data, setData] = useState<any[]>([]);
    
    function fetchData(url: string): void {
        fetch(url)
          .then(response => response.json())
          .then(data => setData(data));
    }
    

    Nota: A propriedade de gradeautoGenerate é melhor evitar ao vincular dados remotos por enquanto. Ele assume que os dados estão disponíveis para inspecioná-los e gerar as colunas apropriadas. Isso geralmente não acontece até que o serviço remoto responda, e a grade gera um erro. DisponibilizarautoGenerate, quando vinculado ao serviço remoto, está no nosso roteiro para versões futuras.

    Complex Data Binding

    A vinculação de dados complexos permite uma interação perfeita com dados de vários níveis, conjuntos de dados complexos do mundo real, módulos de dados orientados a objetos, etc. Usando nosso React Data Grid, você pode facilmente associar a objetos complexos (incluindo estruturas de dados que se aninham mais profundamente do que um nível). Isso acontece por meio de um caminho de propriedades no registro de dados.

    Dê uma olhada no seguinte modelo de dados:

    interface AminoAcid {
        name: string;
        abbreviation: {
            short: string;
            long: string;
        }
        weight: {
            molecular: number;
            residue: number;
        },
        formula: {
            molecular: string;
            residue: string;
        }
    }
    

    Por exemplo, para exibir os pesos de um determinado aminoácido na grade, o seguinte trecho será suficiente

    <IgrColumn field="weight.molecular"></IgrColumn>
    <IgrColumn field="weight.residue"></IgrColumn>
    

    Uma forma alternativa de vincular dados complexos, ou de visualizar dados compostos (de mais de uma coluna) noIgrGrid é usar um modelo personalizado de corpo para a coluna. Geralmente, pode-se:

    • use ovalue da célula, que contém os dados aninhados
    • use ocell objeto no template, a partir do qual acessar octx.cell.id.rowIndex ouctx.cell.id.rowID obter a linha via API da grade e recuperar qualquer valor dela e interpolar esses no template.
    function getName(rowIndex: number) {
        return grid.current.getRowByIndex(rowIndex).data["Name"];
    }
    function getWeight(rowIndex: number) {
        return grid.current.getRowByIndex(rowIndex).data["weight"]["molecular"];
    }
    
    function abbreviationLongCellTemplate(ctx: IgrCellTemplateContext) {
        return (
            <>
                <div>
                <div>
                    { ctx.cell.value }
                        {getName(ctx.cell.id.rowIndex)}
                        {getWeight(ctx.cell.id.rowIndex)}
                </div>
            </div>
            </>
        )
    }
    
    <IgrColumn field="abbreviation.long" bodyTemplate={abbreviationLongCellTemplate}></IgrColumn>
    

    Aqui está um exemplo de como o modelo de corpo é usado para exibir dados complexos. Abaixo estão os dados que vamos usar:

    export const EMPLOYEE_DATA = [
        {
            Age: 55,
            Employees: [
                {
                    Age: 43,
                    HireDate: new Date(2011, 6, 3),
                    ID: 3,
                    Name: "Michael Burke",
                    Title: "Senior Software Developer"
                },
                {
                    Age: 29,
                    HireDate: new Date(2009, 6, 19),
                    ID: 2,
                    Name: "Thomas Anderson",
                    Title: "Senior Software Developer"
                },
                {
                    Age: 31,
                    HireDate: new Date(2014, 8, 18),
                    ID: 11,
                    Name: "Monica Reyes",
                    Title: "Software Development Team Lead"
                },
                {
                    Age: 35,
                    HireDate: new Date(2015, 9, 17),
                    ID: 6,
                    Name: "Roland Mendel",
                    Title: "Senior Software Developer"
                }],
            HireDate: new Date(2008, 3, 20),
            ID: 1,
            Name: "John Winchester",
            Title: "Development Manager"
        }
    ]
    

    O modelo personalizado para a coluna, que renderizará os dados aninhados:

    function addressCellTemplate(ctx: IgrCellTemplateContext) {
        if (ctx.cell.value != null) {
            if (ctx.cell.value.length === 0) return <></>;
            const value = ctx.cell.value[0];
            return (
              <>
                  <IgrExpansionPanel>
                      <div slot="title" style={{fontSize: "1.1em", fontWeight: "bold", marginTop: "1rem", marginBottom: "0.25rem"}}>
                          {value.Name}
                      </div>
                      <div className="description">
                          <IgrInput type="text" label="Title" name="title" value={value.Title} style={{textOverflow: "ellipsis"}}
                              onInput={(e: CustomEvent<string>) => {
                                  ctx.cell.value[0][e.target.label] = e.detail;
                                  grid.current.markForCheck();
                              }} />
                          <IgrInput type="number" label="Age" name="title" value={value.Age} style={{textOverflow: "ellipsis"}}
                              onInput={(e: CustomEvent<string>) => {
                                  ctx.cell.value[0][e.target.label] = e.detail;
                                  grid.current.markForCheck();
                              }} />
                      </div>
                  </IgrExpansionPanel>
              </>
            );
        }
        return <></>;
    }
    
    <IgrColumn field="Employees" header="Employees" width="40%" bodyTemplate={addressCellTemplate}></IgrColumn>
    

    E o resultado dessa configuração é:

    Working with Flat Data Overview

    A abordagem de ligação de dados planos é semelhante à que já descrevemos acima, mas em vez do valor da célula, vamos usar adata propriedade de oIgrGridRowComponent.

    Como a grade de React é um componente para renderização, manipulação e preservação de registros de dados, ter acesso a cada registro de dados oferece a oportunidade de personalizar a abordagem de manuseamento deles. Odata imóvel oferece essa oportunidade.

    Abaixo estão os dados que vamos usar:

    export const DATA: any[] = [
        {
            Address: "Obere Str. 57",
            City: "Berlin",
            CompanyName: "Alfreds Futterkiste",
            ContactName: "Maria Anders",
            ContactTitle: "Sales Representative",
            Country: "Germany",
            Fax: "030-0076545",
            ID: "ALFKI",
            Phone: "030-0074321",
            PostalCode: "12209",
            Region: null
        }
    ]
    

    O modelo personalizado:

    function getCountry(rowIndex: number) {
        return grid.current.getRowByIndex(rowIndex).data["Country"];
    }
    
    function getCity(rowIndex: number) {
         return grid.current.getRowByIndex(rowIndex).data["City"];
    }
    
    function getPostalCode(rowIndex: number) {
         return grid.current.getRowByIndex(rowIndex).data["PostalCode"];
    }
    
    function addressCellTemplate(ctx: IgrCellTemplateContext) {
        var cell: IgrCellType = ctx.cell;
        if (cell === undefined || cell.row === undefined || cell.row.data === undefined) {
            return <></>;
        }
    
        return (
            <>
                <div className="address-container">
                    <div className="country-city">
                        <span><strong>Country:</strong> {cell.row.data.Country}</span>
                        <br/>
                        <span><strong>City:</strong> {cell.row.data.City}</span>
                    </div>
                    <div className="phone-pscode">
                        <span><strong>Postal Code:</strong> {cell.row.data.PostalCode}</span>
                        <br/>
                        <span><strong>Phone:</strong> {cell.row.data.Phone}</span>
                    </div>
                    <br />
                </div>
            </>
        );
    }
    
    <IgrColumn field="Address" header="Address" width="25%" editable={true} bodyTemplate={addressCellTemplate}></IgrColumn>
    

    Lembre-se de que, com o modelo definido acima, você não poderá fazer operações de edição, portanto, precisamos de um modelo de editor.

    function addressEditCellTemplate(ctx: IgrCellTemplateContext) {
        var cell: IgrCellType = ctx.cell;
        if (cell === undefined || cell.row === undefined || cell.row.data === undefined) {
            return <></>;
        }
    
        return (
            <>
                <div className="contact-container--edit" style={{padding: "1rem"}}>
                    <IgrInput
                        label="Country"
                        onInput={(e: CustomEvent<string>) => cell.row.data.Country = e.detail}
                        value={cell.row.data.Country}
                    ></IgrInput>
                    <IgrInput
                        label="City"
                        onInput={(e: CustomEvent<string>) => cell.row.data.City = e.detail}
                        value={cell.row.data.City}
                    ></IgrInput>
                    <IgrInput
                        label="Postal Code"
                        onInput={(e: CustomEvent<string>) => cell.row.data.PostalCode = e.detail}
                        value={cell.row.data.PostalCode}
                    ></IgrInput>
                    <IgrInput
                        label="Phone"
                        onInput={(e: CustomEvent<string>) => cell.row.data.Phone = e.detail}
                        value={cell.row.data.Phone}
                    ></IgrInput>
                </div>
            </>
        );
    }
    
    <IgrColumn field="Address" dataType="number" width="25%" editable={true} inlineEditorTemplate={addressEditCellTemplate}></IgrColumn>
    

    Working with Flat Data Example

    Usar trechos de código da seção anterior resultará no seguinte exemplo deIgrGrid

    Keyboard Navigation

    A navegaçãoIgrGrid por teclado oferece uma rica variedade de interações com o teclado para o usuário. Ele melhora a acessibilidade e permite uma navegação intuitiva por qualquer tipo de elemento interno (célula, linha, cabeçalho de coluna, barra de ferramentas, rodapé, etc.).

    Styling React Grid

    Nota: A grade usa o layout de grade css, que não é suportado no IE sem prefixação, conseqüentemente não será renderizado corretamente.

    Além dos temas predefinidos, a grade pode ser personalizada ainda mais definindo algumas das propriedades CSS disponíveis. Caso você queira alterar o plano de fundo do cabeçalho e a cor do texto, você precisa definir uma classe para a grade primeiro:

    <IgrGrid className="grid"></IgrGrid>
    

    Depois, defina as--header-background propriedades e--header-text-color CSS para essa classe:

    .grid {
        --header-background: #494949;
        --header-text-color: #FFF;
    }
    

    Known Limitations

    Limitação Descrição
    As larguras das colunas definidas empercentage epx Atualmente, não oferecemos suporte à mistura de larguras de coluna com% epx.
    Ao tentar filtrar uma coluna do tiponumber Se um valor diferente do inseridonumber na entradaNaN de filtragem for retornado devido a uma conversão incorreta.
    A gradewidth não depende das larguras das colunas Owidth de todas as colunas não determina a abrangência da grade em si. Ele é determinado pelas dimensões do contêiner pai ou pela grade definida.width
    Grade aninhada no contêiner pai Quando awidth grade não está definida e é colocada em um contêiner pai com dimensões definidas, a grade se estende até esse contêiner.
    As colunas têm uma largura mínima permitida. Dependendo da--ig-size variável CSS, eles são os seguintes:
    "pequeno": 56px
    "médio": 64px
    "grande": 80px
    Se a largura for menor que o mínimo permitido for definida, isso não afetará os elementos renderizados. Eles serão renderizados com a largura mínima permitida para o correspondente--ig-size. Isso pode levar a um comportamento inesperado com a virtualização horizontal e, portanto, não é suportado.
    A altura da linha não é afetada pela altura das células que não estão renderizadas no momento. Devido à virtualização, uma coluna com um modelo personalizado (que altera a altura da célula) que não está no modo de exibição não afetará a altura da linha. A altura da linha será afetada somente enquanto a coluna relacionada for rolada na exibição.

    API References

    Additional Resources

    Nossa comunidade é ativa e sempre acolhedora para novas ideias.