Tabelas de vários níveis (dentro de outra se clicadas)

Cenário

Vamos dizer que eu sou dono de uma grande empresa que tem muitas lojas. Dependendo de qual papel (lugar na organização) eu tenho dentro da empresa, terei access diferente aos dados. Haverá módulos diferentes e, para essa pergunta específica, há um em que os usuários que têm access podem passar pelos custos e vendas diários. (Se isso é legal ou não … não se importe, é apenas para um exemplo.)

Assim, o usuário obtém todos os dados por meio da API REST do BackEnd (aplicativo Java) com todos os dados de todas as lojas às quais o usuário tem access. O usuário deve então poder filtrar os dados por diferentes combinações de filtros. O mais relevante para a minha pergunta é o intervalo de datas por dia.

Haverá alguns charts mostrando dados em diferentes níveis e abaixo haverá uma área da tabela onde eu quero as tabelas multi-nível, daí a minha pergunta.

Feito até agora

  1. Primeiro criei acordeons que têm lojas no nível do grupo do acordeão e, em seguida, o próximo nível de dados em uma tabela, dentro do corpo do acordeão. (Somente dados codificados no momento.) O problema aqui era que um header de acordo é uma string e depois de alguma discussão sentimos que essa não era uma boa solução, pois o header consistiria em partes de dados que em uma tabela teriam sido colunas separadas. Seria, portanto, difícil “colocar em coluna” os dados dos headers para combinar horizontalmente as diferentes “lojas” (entre os títulos do acordeão) quando colapsadas (e, claro, ainda mais confusas quando um ou mais acordeões são expandidos).
  2. Eu substituí os acordeões por mesa e repetição. Ter preenchido com êxito o primeiro nível da tabela com os dois dados da API figurativa com dados JSON, além de ter o i18next funcionando para os títulos.

JSON

{ "metadata":{ "storesInTotal":"25", "storesInRepresentation":"2" }, "storedata":[ { "store" : { "storeId" : "1000", "storeName" : "Store 1", "storePhone" : "+46 31 1234567", "storeAddress": "Some street 1", "storeCity" : "Gothenburg" }, "data" : { "startDate" : "2013-07-01", "endDate" : "2013-07-02", "costTotal" : "100000", "salesTotal" : "150000", "revenueTotal" : "50000", "averageEmployees" : "3.5", "averageEmployeesHours" : "26.5", "dayData" : [ { "date" : "2013-07-01", "cost" : "25000", "sales" : "15000", "revenue" : "4000", "employees" : "3", "employeesHoursSum" : "24" }, { "date" : "2013-07-02", "cost" : "25000", "sales" : "16000", "revenue" : "5000", "employees" : "4", "employeesHoursSum" : "29" } ] } }, { "store" : { "storeId" : "2000", "storeName" : "Store 2", "storePhone" : "+46 8 9876543", "storeAddress": "Big street 100", "storeCity" : "Stockholm" }, "data" : { "startDate" : "2013-07-01", "endDate" : "2013-07-02", "costTotal" : "170000", "salesTotal" : "250000", "revenueTotal" : "80000", "averageEmployees" : "4.5", "averageEmployeesHours" : "35", "dayData" : [ { "date" : "2013-07-01", "cost" : "85000", "sales" : "120000", "revenue" : "35000", "employees" : "5", "employeesHoursSum" : "38" }, { "date" : "2013-07-02", "cost" : "85000", "sales" : "130000", "revenue" : "45000", "employees" : "4", "employeesHoursSum" : "32" } ] } } ], "_links":{ "self":{ "href":"/storedata/between/2013-07-01/2013-07-02" } } } 

Exemplo visual – JSFiddle

Verifique os valores no quadro de resultados, no canto superior esquerdo. Tente clicar, por exemplo, na linha com o ID da loja 2000, depois com 3000 e depois com 3000 novamente para ver como os valores mudam. Atualização atual do meu JSFiddle

Funcionalidade desejada

Quando uma linha é clicada (como mostrado no JSFiddle), eu quero uma diretiva ou algo triggersdo, para ir buscar dados subjacentes (dayData) para a loja clicada e mostrar todos os dias no intervalo de datas. Ou seja, expandir a linha e include uma nova tabela na linha clicada, que também deve usar ng-repeat para obter todos os dados exibidos semelhantes aos existentes, mas inline.

Questão

Então, eu já tenho a funcionalidade para obter o índice $ e também os dados específicos da linha clicada. Que tipo de diretiva ou qualquer outra solução eu preciso adicionalmente para obter os “dados quando a linha clicou” e apresentados em uma tabela sob a linha clicada?

Eu não quero isso no DOM o tempo todo, já que pode haver muitos dayData para cada loja e muitas lojas. (E vai usar paginação mais tarde, mas mesmo assim, não no DOM o tempo todo.) Isso significa que eu tenho que ser capaz de adicionar ao clicar em uma linha, e ao clicar no mesmo ou outro REMOVER do clicado anteriormente.


EDITAR

Novo JSFiddle atualizado .

O requisito era não preencher o DOM com todas as tabelas de segundo nível e eu encontrei uma solução para ele.

Primeiro, tentei criar uma diretiva personalizada e consegui inserir uma linha no lugar certo (abaixo da linha clicada) e criei uma tabela de segundo nível com headers, mas não consegui obtê-la para preencher com linhas usando ng-repeat.

Como não consegui encontrar uma solução que funcionasse plenamente voltei ao que já tinha criado, com ng-show e procurei uma solução como esta … e existe uma. Em vez de usar ng-show / ng-hide, o Angular possui uma diretiva chamada ng-switch.

No nível um

  

… e depois no segundo nível, ou seja, o segundo tr

  

, em que você tem o segundo nível ng-repeat.

Aqui está um novo JSFiddle .

Inspecione os elementos e você verá que há um espaço reservado de comentário para cada tabela de nível 2 “recolhida”.


ATUALIZAÇÃO (2014-09-29)

A pedido de expandir / reduzir o nível 3, aqui está um novo JSFIDDLE .

NOTA! – Esta solução tem todas as informações no DOM em todos os momentos, ou seja, não como a solução anterior, que apenas adicionou uma notação para onde as informações devem ser adicionadas mediante solicitação.

(Eu não posso levar o crédito deste, já que meu amigo Axel bifurcou o meu e depois adicionou a funcionalidade.)

Eu acho que uma solução melhor é usar as diretivas ng-repeat-start e ng-repeat-end nos elementos tr em vez de usar o ng-repeat no corpo (este caso não justifica mais do que um único corpo).

Dê uma olhada aqui:

PLNKR

      {{person.name}} {{person.gender}}   {{person.details}}  

Eu ainda não tenho reputação suficiente para comentar, então estou respondendo com uma questão de funcionalidade adicional que eu já vi. Eu usei a estrutura do Pixic com sucesso, pois eu realmente gosto que o DOM não esteja poluído com os dados / tabelas do segundo nível até que eles sejam visualizados e tudo esteja funcionando perfeitamente.

Até que me pediram para permitir a sorting dinâmica da tabela de nível superior. Não há problema – eu posso classificar a tabela de nível superior. O problema é que não consegui encontrar uma maneira de manter a tabela de segundo nível (ou seja, oculta) sincronizada e “em movimento” com o tipo de tabela de nível superior. Este é apenas um problema de exibição. Os dados subjacentes estão adequadamente associados ao nível superior, mas a exibição está confusa à medida que exibe a linha “indexada” original, pois as tabelas de segundo nível não são reordenadas com a linha pai.

A única coisa que posso fazer é inserir dinamicamente o segundo nível de HTML do controlador ao expandir uma linha, mas me pergunto se alguém mais teve outras ideias. Eu tentei ng-repeat-start e ng-repeat-end (em uma terceira tag tr oculta para include todos os elementos que deveriam manter todos os itens juntos, e em um corpo oculto), mas isso não funcionou.

Edit: Conforme solicitado, iniciei outra pergunta: tabelas de vários níveis (dentro de outra se clicada) e sorting dinâmica da tabela de nível superior