Angular.js ng-repeat em vários tr's

125

Estou usando o Angular.js para um aplicativo que usa trs ocultos para simular um efeito deslizante, mostrando o tr e deslizando a div no td abaixo. Esse processo funcionou de maneira fantástica usando o knockout.js ao iterar sobre uma matriz dessas linhas, porque eu poderia usar os <!-- ko:foreach -->dois elementos tr.

Com angular, ng-repeatdeve ser aplicado a um elemento html, o que significa que não consigo repetir essas linhas duplas usando métodos padrão. Minha primeira resposta a isso foi criar uma diretiva para representar esses trs duplos, mas isso ficou aquém porque os modelos de diretiva devem ter um único elemento raiz, mas eu tenho dois ( <tr></tr><tr></tr>).

Se alguém com experiência com ng-repeat e angular que quebrou isso puder explicar como resolver esse problema, ficaria muito grato.

(Devo também observar que anexar ng-repeatao tbody é uma opção, mas isso produz vários tbodys, e estou assumindo que essa é uma má forma para o HTML padrão, embora me corrija se estiver errado)

thegreenpizza
fonte

Respostas:

168

Usar ng-repeaton tbodyparece ser válido, veja esta postagem .

Também um teste rápido através de um validador html permitiu vários tbodyelementos na mesma tabela.

Atualização: Desde pelo menos o Angular 1.2, existe um ng-repeat-starte ng-repeat-endpara permitir a repetição de uma série de elementos. Consulte a documentação para obter mais informações e obrigado a @Onite pelo comentário!

Gloopy
fonte
Fantástico. Eu tive o mesmo problema e realmente pensei em fazer isso, mas pensei que nunca iria funcionar apenas repetindo a tag tbody. Obrigado!
precisa saber é o seguinte
11
Está um pouco depois do fato agora, mas o Angular 1.2 introduziu as diretivas ng-repeat-start e ng-repeat-end para permitir a iteração de vários elementos.
Onite 22/11/2013
1
@Onite É muito mais tarde agora e estou usando o AS 1.5, mas não sabia sobre a funcionalidade adicional de início e fim do ng-repeat. Você apontou o meu para que nunca se desculpe por adicionar informações a uma resposta.
Neville
1
O URL para a documentação de repetição do ng está incorreto, mas a alteração não é superior a seis caracteres, portanto, não posso editá-lo sem adicionar apenas uma meta edição inútil. O URL correto deve ser docs.angularjs.org/api/ng/ directiva / ngRepeat
Bill Rawlinson
35

O desenvolvedor do AngularJS @ igor-minar respondeu isso no Angular.js ng-repeat em vários elementos .

Miško Hevery implementou recentemente o suporte adequado via ng-repeat-starte ng-repeat-end. Esse aprimoramento não foi lançado a partir de 1.0.7 (estável) e 1.1.5 (instável).

Atualizar

Agora está disponível no 1.2.0rc1. Confira os documentos oficiais e este screencast de John Lindquist.

Anson
fonte
Ele menciona isso na transmissão ao vivo do Angular, a partir de 11 de junho de 2013. Ansioso por esse e outros recursos no Angular 1.1.5+ e Angular 2.0.
precisa
Estou apontando para o 1.1.5 no cdnjs cdn e isso não está funcionando. //cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js você sabe em qual versão ela deve estar disponível?
Shanimal 13/07/2013
Correto, não foi lançado a partir do 1.1.5, então assista ao 1.1.6 (ou muito provavelmente 1.2.0) para pousar em breve. Aqui está o compromisso de Miško de aguardar o
Anson
Também é bom notar que isso funciona para todas as diretivas, não apenas ngRepeat;)
7hi4g0
4

Ter vários elementos pode ser válido, mas se você estiver tentando criar uma grade rolável com cabeçalhos / rodapés fixos, o seguinte poderá não funcionar. Este código assume o seguinte CSS, jquery e AngularJS.

HTML

<table id="tablegrid_ko">
        <thead>
            <tr>
                <th>
                   Product Title
                </th>
                <th>
                </th>
            </tr>
        </thead>

        <tbody ng-repeat="item in itemList">
            <tr ng-repeat="itemUnit in item.itemUnit">
                <td>{{itemUnit.Name}}</td>
            </tr>
        </tbody>
</table>

CSS para criar cabeçalho / rodapé fixo para grade de tabela rolável

#tablegrid_ko {
    max-height: 450px;    
}
#tablegrid_ko
{
border-width: 0 0 1px 1px;
border-spacing: 0;
border-collapse: collapse;
border-style: solid;
}

#tablegrid_ko td, #tablegrid_ko th
{
margin: 0;
padding: 4px;
border-width: 1px 1px 0 0;
border-style: solid;
}


#tablegrid_ko{border-collapse:separate}
#tablegrid_ko tfoot,#tablegrid_ko thead{z-index:1}
#tablegrid_ko tbody{z-index:0}
#tablegrid_ko tr{height:20px}
#tablegrid_ko tr >td,#tablegrid_ko tr >th{
border-width:1px;border-style:outset;height:20px;
max-height:20px;xwidth:45px;xmin-width:45px;xmax-width:45px;white-space:nowrap;overflow:hidden;padding:3px}

#tablegrid_ko tr >th{
background-color:#999;border-color:#2c85b1 #18475f #18475f #2c85b1;color:#fff;font-weight:bold}
#tablegrid_ko tr >td{background-color:#fff}
#tablegrid_ko tr:nth-child(odd)>td{background-color:#f3f3f3;border-color:#fff #e6e6e6 #e6e6e6 #fff}
#tablegrid_ko tr:nth-child(even)>td{background-color:#ddd;border-color:#eaeaea #d0d0d0 #d0d0d0 #eaeaea}

div.scrollable-table-wrapper{
background:#268;border:1px solid #268;
display:inline-block;height:285px;min-height:285px;
max-height:285px;width:550px;position:relative;overflow:hidden;padding:26px 0}

div.scrollable-table-wrapper table{position:static}
div.scrollable-table-wrapper tfoot,div.scrollable-table-wrapper thead{position:absolute}
div.scrollable-table-wrapper thead{left:0;top:0}
div.scrollable-table-wrapper tfoot{left:0;bottom:0}
div.scrollable-table-wrapper tbody{display:block;position:relative;overflow-y:scroll;height:283px;width:550px}

Jquery para vincular a rolagem horizontal de tbody, isso não funciona porque eles se repetem durante a repetição de ng.

$(function ($) {

$.fn.tablegrid = function () {


        var $table = $(this);
        var $thead = $table.find('thead');
        var $tbody = $table.find('tbody');
        var $tfoot = $table.find('tfoot');

        $table.wrap("<div class='scrollable-table-wrapper'></div>");

        $tbody.bind('scroll', function (ev) {
            var $css = { 'left': -ev.target.scrollLeft };
            $thead.css($css);
            //$tfoot.css($css);
        });


    }; // plugin function



}(jQuery));
phanf
fonte
0

Você pode fazer isso dessa maneira, como mostrei nesta resposta: https://stackoverflow.com/a/26420732/769900

<tr ng-repeat="m in myData">
   <td>{{m.Name}}</td>
   <td>{{m.LastName}}</td>

   <td ng-if="$first" rowspan="{{myData.length}}">
       <ul>
           <li ng-repeat="d in days">
               {{d.hours}}
           </li>
       </ul>
   </td> 
</tr>
Jeff Tian
fonte