Material-ui: [docs] Tabela virtualizada

Criado em 17 jul. 2017  ·  55Comentários  ·  Fonte: mui-org/material-ui

@oliviertassinari você consideraria adicionar um contêiner virtual ao tbody para aumentar o desempenho ao renderizar listas longas sem paginação?
Vou tentar fazer isso se você puder apenas me apontar a direção certa ( react-virtualized ?)

Table docs good first issue

Comentários muito úteis

@oliviertassinari Fiz sem react-virtualized porque estava uma bagunça e não combinava com os componentes do mui.
Além disso, minha solução atual é um tbody de cabeçalho fixo e rolável puro-css com altura de mesa dinâmica e largura de colunas dinâmicas (testado no Safari também).
O thead sempre no topo com um tbody rolável é uma obrigação para grades de dados.

Eu estou adicionando o scroll debouncing, aprimorando o desempenho e consertando algumas falhas, mas está funcionando muito bem: estou "virtualmente" renderizando cerca de 2400 linhas, muuuito suave.

out

Perguntas sobre componentes de Table :

  1. como usar ref com componentes MUI? Estou computando TableThead altura automaticamente: o problema é que
<TableHead ref={ ref => this.tableThead = ref }>

não está retornando o elemento do contêiner DOM real de TableThead mas a instância React (comportamento nativo do React ao aplicar ref em um elemento não-DOM) porque isso é algo que deve ser aplicado no TableThead próprio componente; outros componentes podem precisar disso, então por que não ter um refHandler em cada componente MUI que aplica o retorno de chamada fornecido no primeiro elemento renderizado? (Espero ter conseguido explicar isso @ _ @)
Minha solução atual é estranha

const theadHeight = ReactDOM.findDOMNode(this.tableThead).clientHeight; // eslint-disable-line react/no-find-dom-node

o que significa usar o obsoleto findDomNode e desabilitar o eslint também.

  1. por que border-bottom aplicado em células em vez de linhas?

  2. que tal ter um stripe={true} prop para riscar automaticamente TableBody linhas?

  3. por que .MuiIconButton.root tem uma propriedade de estilo zIndex? 🤔

Espero publicar algo estável sobre isso em breve para que você possa dar uma olhada, é algo que pode ser adotado de uma forma geral.

Desculpe incomodar tanto, mas estou usando muito mui @ next, então estou identificando muitos casos de uso!

Todos 55 comentários

Esperamos que a API atual permita uma integração simples com react-virtualized . Estamos abertos para fazer qualquer alteração na implementação para tornar a integração mais simples.

Ter um exemplo de demonstração nos documentos seria incrível.

Se isso pode ajudar, aqui está um exemplo de integração com a Lista / Menu https://codesandbox.io/s/oQ0nkl5pk.

@oliviertassinari Fiz sem react-virtualized porque estava uma bagunça e não combinava com os componentes do mui.
Além disso, minha solução atual é um tbody de cabeçalho fixo e rolável puro-css com altura de mesa dinâmica e largura de colunas dinâmicas (testado no Safari também).
O thead sempre no topo com um tbody rolável é uma obrigação para grades de dados.

Eu estou adicionando o scroll debouncing, aprimorando o desempenho e consertando algumas falhas, mas está funcionando muito bem: estou "virtualmente" renderizando cerca de 2400 linhas, muuuito suave.

out

Perguntas sobre componentes de Table :

  1. como usar ref com componentes MUI? Estou computando TableThead altura automaticamente: o problema é que
<TableHead ref={ ref => this.tableThead = ref }>

não está retornando o elemento do contêiner DOM real de TableThead mas a instância React (comportamento nativo do React ao aplicar ref em um elemento não-DOM) porque isso é algo que deve ser aplicado no TableThead próprio componente; outros componentes podem precisar disso, então por que não ter um refHandler em cada componente MUI que aplica o retorno de chamada fornecido no primeiro elemento renderizado? (Espero ter conseguido explicar isso @ _ @)
Minha solução atual é estranha

const theadHeight = ReactDOM.findDOMNode(this.tableThead).clientHeight; // eslint-disable-line react/no-find-dom-node

o que significa usar o obsoleto findDomNode e desabilitar o eslint também.

  1. por que border-bottom aplicado em células em vez de linhas?

  2. que tal ter um stripe={true} prop para riscar automaticamente TableBody linhas?

  3. por que .MuiIconButton.root tem uma propriedade de estilo zIndex? 🤔

Espero publicar algo estável sobre isso em breve para que você possa dar uma olhada, é algo que pode ser adotado de uma forma geral.

Desculpe incomodar tanto, mas estou usando muito mui @ next, então estou identificando muitos casos de uso!

Fiz sem reagir virtualizado porque era uma bagunça e não combinava com os componentes mui.

Oh, isso é uma pena para nós. Alguma ideia do que poderíamos fazer para tornar possível?

  1. Você pode tentar innerRef para obter uma referência sobre TableHead . ref lhe dará uma referência sobre o componente withStyles(TableHead) . Se isso não funcionar, podemos expor uma propriedade rootRef . Esse é um padrão que já estamos usando.

  2. Nenhuma pista

  3. O que você quer dizer com faixa?
  4. Eu removi em # 7467

~~Oh, isso é uma pena para nós.

Na verdade, é uma mistura de react-virtualized containers próprios, elementos nativos table/thead/tbody DOM e a necessidade de ter um tbody rolável que causou o problema.
Era necessário muito trabalho com isso: simplesmente fazer uma solução ad-hoc para MuiTable era uma brisa.

  1. expor um rootRef seria ótimo (supondo que TableThead elemento principal no método render seja o próprio elemento Thead DOM)

  2. border-bottom ser movido para tr então? Devo mover isso para um problema dedicado?

  3. Quero dizer linhas listradas: fácil de conseguir com like tr:nth-child(odd) { backgroundColor: f2f2f2 mas como já temos a coloração hover={true} por que não ter a striped={true} ? :)

  4. ótimo!

  1. 👍 Parece um plano, aqui está um exemplo , um RP é bem-vindo.
  2. O Bootstrap está fazendo o mesmo , acho que está fornecendo mais flexibilidade ao usá-lo no TableCell .
  3. Porque não está na especificação e pode ser implementado simplesmente no espaço do usuário?
  4. 👍
  1. Não tenho certeza sobre simplesmente ter ref={rootRef} em cada componente.
    Os desenvolvedores que o estão usando provavelmente (principalmente) precisam ter controle sobre o DOM.
    Em seu exemplo, <FormControl ref={rootRef} ...> retornará novamente uma referência ao componente React (porque FormControl não é um elemento DOM) e fará com que o desenvolvedor use a solução alternativa que eu tive que usar.
    Talvez devêssemos fazer com que rootRef se comportasse da seguinte forma:

O contêiner do componente renderizado é um elemento DOM?

  • se sim, aplique ref={rootRef} nele
  • caso contrário, aplique rootRef={rootRef} nele => que se propagará para o primeiro elemento DOM: desta forma, o codificador sempre terá a referência real do DOM

A solução abrangente em que posso pensar é ter muiRef e rootRef propriedades em que o primeiro aplica o retorno de chamada ao contêiner "mui componente" (se houver) e o último aplica o retorno de chamada como eu disse antes.
Desta forma, o Desenvolvedor pode facilmente ter ambos / ambos MUI ref e DOM ref (o que ele precisar, sempre que ele precisar).
Você acha que isso faz sentido?

  1. mesmo? @ _ @

  2. ops! Eu sempre esqueço as especificações do material

  1. Oh, eu não pensei sobre esse caso. O problema ao qual você está se referindo é o seguinte:
  2. O componente A leva uma propriedade ref e rootRef
  3. Reaja interceptar ref e aplique-o no elemento
  4. O componente B recebe uma propriedade rootRef e aplica-a como uma referência no componente C raiz
  5. React interceptar este ref e aplicá-lo no elemento

Mas e se o Componente C também tiver uma propriedade rootRef?
O Componente A pode estar no terreno do usuário, o Componente B pode ser o TextField e o Componente C pode ser o FormControl.

Portanto, minha resposta: primeiro, apresentamos rootRef como um auxiliar simples. Não pensamos na industrialização. Então, eu acho que o comportamento atual é ótimo como determinístico, simples e sem a limitação que você está descrevendo, se as pessoas estiverem interessadas em acessar o elemento dom subjacente, elas podem usar a API findDOMNode .

@damianobarbati O -virtual-list foi o experimento com Tabela e virtualização mencionado aqui ?

Estou supondo que listComponent = TableBody, itemComponent = TableRow?

Comecei este projeto que usa a virtualização reativa com o Material 1.0, no qual você pode estar interessado.

https://github.com/techniq/mui-table

Ainda é um trabalho em andamento (consulte https://github.com/techniq/mui-table/blob/master/TODO.md), mas pode ser útil para você. Faltam documentos, mas dê uma olhada nas histórias para ter uma ideia de como usá-los.

@techniq Isso parece promissor 😄! Acho que seria ótimo renovar a seção de documentação da tabela em algum momento para ter:
- https://github.com/DevExpress/devextreme-reactive~~ (licença comercial)

Também podemos adicioná-lo à seção https://material-ui-next.com/discover-more/related-projects/#material-ui-specific-projects.
Então, avise-nos quando o projeto estiver mais maduro. Acho que podemos aceitar um pedido de pull para promover o projeto :).

Eu fiz um PR para react-virtual-list aqui https://github.com/clauderic/react-tiny-virtual-list/pull/30 que permite seu uso com material-ui. Lutei para fazer o react-virtual funcionar e criar um HTML válido, uma vez que div está codificado.

cc: @kgregory

@eyn bom trabalho! Acabei de concluir a implementação de uma tabela de rolagem infinita usando react-virtualized e material-ui. Espero lançar uma ideia geral em breve. Quando o fizer, vou vinculá-lo aqui para quaisquer futuros visitantes desta edição e, possivelmente, como um exemplo nos documentos.

@kgregory você terminou sua essência? Ainda estou procurando uma solução básica para tabela de IU de material virtualizada e não é fácil de encontrar ... Seria uma grande ajuda!

Obrigado pelo seu trabalho!

@neofox Não, desculpe. Eu nunca tive tempo para isso, mas sua resposta é um bom lembrete. Vou tentar encontrar tempo para montar algo.

@oliviertassinari seu exemplo em um dos primeiros comentários que supostamente mostra como usar a lista de materiais com a lista virtualizada

@rolandjitsu Desculpe, não tenho exemplos. É sobre o que trata este problema :).

@oliviertassinari entendeu. Achei que esse problema fosse sobre a mesa e não sobre <List> , ou também abrange as listas?

@rolandjitsu A lista, a mesa, o papel, a lista de grade. É tudo a mesma coisa. Este problema é sobre como adicionar uma demonstração simples para que as pessoas possam ver o padrão e aplicá-lo a diferentes componentes. A mesa é um componente do qual você provavelmente precisará de virtualização.

@oliviertassinari Eu gostaria de dar uma chance a isso, se você puder me indicar a direção certa. Pelo que eu posso dizer, precisamos de uma essência básica com material-ui @ next integrado com react-virtualized?

@ hassan-zaheer Sim, acho que uma demonstração simples com react-virtualized no final da página de documentação das tabelas resolverá o problema :).

Oi. Aconteceu de tropeçar neste tópico ao pesquisar para meu projeto. Gostaria de saber se há alguma atualização aqui em relação à demonstração ou documentação de uso? @kgregory Ou você pode fornecer alguma ideia sobre como incorporar os dois? Seria bom fazer a mesa parecer coerente com o estilo

@ zd-project Você pode dar uma olhada no meu projeto mui-virtualized-table .

Costumava ser mui-table, mas decidi bifurcar os 2 e oferecer suporte a diferentes casos de uso ( mui-table aproveita o DOM diretamente e permite que você use coisas como position: sticky e layout <table> (extensões de linha / coluna, larguras automáticas, etc) que eram difíceis com a virtualização reativa.

Com isso dito, mui-virtualized-table acabou de adicionar redimensionamento de coluna a partir de um bom PR.

Onde estamos nesse pessoal?

@techniq , obrigado por mui-virtualized-table ! É ótimo! Há alguma chance de mesclá-lo em mui-org/material-ui ?

Eu ficaria feliz se alguém abrisse um PR que apresenta uma demonstração para os documentos. Dessa forma, poderíamos examinar se podemos melhorar a API da tabela para uma melhor integração com estratégias de virtualização.

@mastertinner Por que precisamos adicionar isso ao núcleo? A virtualização é uma estratégia de otimização. Nem todo mundo renderiza grandes conjuntos de dados, então eu não sobrecarregaria o pacote de todos com isso.

@mastertinner Podemos começar referenciando o projeto na documentação, por exemplo aqui: https://material-ui.com/demos/tables/#advanced-use-cases :)

👍 parece um plano

@mastertinner Embora eu ainda o use (quando a virtualização é necessária), também uso minha mui-table mais recente quando não preciso de uma virtualização e posso alavancar o dom (usando table , tr , td ou grade css para layout, removendo a necessidade de larguras de coluna explícitas, etc) e permite alguns padrões avançados, como vários cabeçalhos position: sticky (como este )

@rogerstorm financiou este problema com $ 30. Veja em IssueHunt

Decidi brincar com isso hoje, não recomendo 😭 Aqui está o que produzi até agora:
virtualize

Desculpe o atraso, meu laptop não está ótimo 👎 Ele usa componentes de IU de materiais e react-virtualized componentes

@joshwooding Fiz exatamente a mesma coisa que você fez, virtualizado + cabeçalho fixo (com barra de rolagem apenas no corpo) . Se sua implementação usa dois <Table> s separados, então acho que você tem os mesmos problemas que encontrei.

  • os adereços de alinhamento do material (por exemplo, numeric ) não funcionam, porque você pode usar um componente como <div> para o layout dentro de <TableCell> .
  • Você pode fornecer propriedades css para td e tr para funcionar virtualizado corretamente. Não há como dar height ou max-height a td e tr e <TableCell> tem seu próprio preenchimento, itens de margem, então é difícil fixar a altura da linha.

Bem, o ponto é que um componente dentro de <TableCell> é inevitável. Eu me pergunto se você resolveu esse problema de uma forma elegante. Do contrário, acho que cabeçalho fixo + virtualizado (com barra de rolagem apenas no corpo) é difícil ser um componente pequeno (tão pequeno quanto sua função) e bem definido.

@worudso Atualmente ele usa apenas um <Table> Eu preciso encontrar uma maneira de passar os números para baixo, mas posso conseguir fazer isso funcionar. Definitivamente não é um componente pequeno e meu código ainda está um pouco confuso, mas vou trabalhar mais um pouco e ver se consigo refiná-lo

Eu criei uma caixa de areia que demonstra o uso de material-ui e react-virtualized para produzir uma mesa virtualizada. Este exemplo particular usa react-virtualized para dimensionar a tabela para a altura da janela.

O componente MuiVirtualizedTable do exemplo também está disponível nesta essência .

MuiVirtualizedTable pode aceitar qualquer prop suportado por uma Mesa . O rowClassName não é aplicado diretamente, mas em vez disso, é aplicado além de outros estilos definidos em MuiVirtualizedTable .

O columns prop espera um array de objetos que é usado ao renderizar células para cada coluna. Cada objeto pode aceitar qualquer suporte suportado pela coluna .

Minhas desculpas por demorar tanto. Eu estive ocupado.

Para sua informação, agora há também react-window que é suposto ser react-virtualized sucessor. No caso de alguém querer experimentar esse.

@kgregory Obrigado por compartilhar o codesandbox.

@joshwooding Ótima demonstração. É ótimo ter um cabeçalho fixo :). Espero que você consiga concluir a implementação! Em relação ao encaminhamento numérico, o que o impede de aplicar diretamente nas células? react-window vs react-virtualized

@oliviertassinari Eu me Table e agora não parece que você pode passar adereços personalizados através do componente Column . Provavelmente, há maneiras de fazer isso sem usar a forma virtualizada de reação, embora

@oliviertassinari Eu tentei usar HeaderRowRenderer, mas parece que você não pode passar adereços personalizados por ele sem manipular os adereços existentes, pois isso é o que é chamado para criar as colunas a serem passadas para o headerRenderer:

const renderedHeader = headerRenderer({ columnData, dataKey, disableSort, label, sortBy, sortDirection, });

@oliviertassinari Para uma mesa de altura fixa, você pode apenas editar um pouco a demonstração de @kgregory : https://codesandbox.io/s/6vo8y0929k

@joshwooding Parece ótimo! Não consigo pensar em nada faltando para torná-lo uma demonstração oficial.

@issuehuntfest financiou $ 60,00 para esta edição. Veja em IssueHunt

@oliviertassinari Vou trabalhar na implementação disso :)

@joshwooding enviou uma solicitação de pull. Veja em IssueHunt

@oliviertassinari recompensou $ 81,00 para @joshwooding. Veja em IssueHunt

  • : bolsa de dinheiro: Depósito total: $ 90,00
  • : tada: Recompensa do repositório (0%): $ 0,00
  • : chave: Taxa de serviço (10%): $ 9,00

@oliviertassinari recompensou $ 81,00 para @joshwooding. Veja em IssueHunt

Bem merecido. Bom trabalho @joshwooding!

Tenho uma necessidade semelhante, mas para o componente Lista ... a mesma abordagem funcionaria para fazer a lista funcionar?

@mdizzy Sim, poderíamos adicionar uma demonstração semelhante para a lista.

Estou tentando agora fazer uma lista virtual com react-window (como o criador sugeriu para usá-lo no lugar de virtualizado se você não precisa da API completa, mas no final a API para uma lista realmente não muda muito)

Até agora, tenho dois grandes problemas:
1) O estilo dos itens da lista está quebrado, especialmente para coisas como ícones / ações corretos. Eu acho que o estilo injetado da lista virtual não combina bem com o estilo do material-ui
2) Subcabeçalhos fixos também ficam muito confusos, provavelmente pelo mesmo motivo (a janela de reação usa a posição absoluta para fazer o layout dos itens)

Provavelmente vou tentar virtualizar por reação para ver se funcionam melhor juntos

@MastroLindus Presumo que você tenha experimentado nossa demonstração de virtualização primeiro.

@oliviertassinari Comecei do meu próprio jeito, encontrei os problemas que descrevi acima, pesquisei no Google, encontrei este tópico.

Então eu descobri sobre a demonstração de virtualização, verifiquei seu código e descobri que é basicamente a mesma coisa que eu mesmo estou fazendo (aplicado apenas a tabelas em vez de listas).

Meus problemas são um pouco mais relacionados a listas. O conceito geral funciona, mas coisas como ícones, ações e cabeçalhos fixos não estão funcionando corretamente.
Em detalhes, referindo-se aos meus 2 pontos no comentário acima:
O problema número 1 pode ser um problema com a janela de reação que não estará presente na virtualização de reação. Eu vou deixar você saber assim que eu tentar hoje ou amanhã. Talvez tenhamos sorte e ele funcionará apenas com virtualizado reativo. Vamos ver.
Problema número 2 (subcabeçalhos fixos não funcionam corretamente) Acho que é algo que vai precisar de uma solução ad-hoc de qualquer maneira, já que seu posicionamento provavelmente criará um conflito de qualquer maneira. Alguém construiu https://github.com/marchaos/react-virtualized-sticky-tree para um problema semelhante (tendo reagido virtualizado com cabeçalhos fixos), mas eu não tive tempo de olhar para isso agora

@MastroLindus Que problemas temos com https://next.material-ui.com/demos/tables/#virtualized -table?

@oliviertassinari Nenhum.
Especifiquei que meus problemas são específicos para listas virtuais, não tabelas virtuais. (Novamente: lamento estar escrevendo sobre o problema da Tabela virtualizada, não há nenhuma para listas virtualizadas e eu estava acompanhando o comentário de @mdizzy )

Em relação às listas: o uso de ListItemSecondaryAction, ListItemIcon e ListSubheader (com cabeçalhos fixos) não parece funcionar, pois seu posicionamento fica confuso.
Sem esses componentes, obtive uma lista básica para trabalhar com react-window (e acho que faria o mesmo em react-virtualized)

@MastroLindus Acho que você pode mover a discussão para # 15149.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

mattmiddlesworth picture mattmiddlesworth  ·  3Comentários

revskill10 picture revskill10  ·  3Comentários

FranBran picture FranBran  ·  3Comentários

sys13 picture sys13  ·  3Comentários

TimoRuetten picture TimoRuetten  ·  3Comentários