Angular.js ng-repeat en múltiples tr's

125

Estoy usando Angular.js para una aplicación que usa trs ocultos para simular un efecto deslizante mostrando el tr y deslizando hacia abajo el div en el td a continuación. Este proceso funcionó fantásticamente usando knockout.js al iterar sobre una matriz de estas filas, porque podría usar <!-- ko:foreach -->alrededor de ambos elementos tr.

Con angular, ng-repeatdebe aplicarse a un elemento html, lo que significa que parece que no puedo repetir estas filas dobles usando métodos estándar. Mi primera respuesta a esto fue crear una directiva para representar estos trs dobles, pero eso se quedó corto porque las plantillas de directivas deben tener un solo elemento raíz, pero tengo dos ( <tr></tr><tr></tr>).

Si alguien con experiencia en ng-repeat y angular que ha resuelto esto puede explicar cómo resolver este problema, lo agradecería mucho.

(También debo tener en cuenta que adjuntar ng-repeatal tbody es una opción, pero esto produce múltiples tbodys, y supongo que es una forma incorrecta para HTML estándar, aunque corrígeme si me equivoco)

thegreenpizza
fuente

Respuestas:

169

Usar ng-repeaton tbodyparece ser válido ver esta publicación .

También una prueba rápida a través de un validador html permitió múltiples tbodyelementos en la misma tabla.

Actualización: a partir de al menos Angular 1.2 hay un ng-repeat-starty ng-repeat-endpara permitir repetir una serie de elementos. Consulte la documentación para obtener más información y gracias a @Onite por el comentario.

Gloopy
fuente
Fantástico. Tuve el mismo problema y en realidad debatí hacer esto, pero pensé que nunca funcionaría simplemente iterando en la etiqueta tbody. ¡Gracias!
KhalilRavanna
12
Es un poco posterior al hecho ahora, pero Angular 1.2 introdujo las directivas ng-repeat-start y ng-repeat-end para permitirle iterar sobre múltiples elementos.
Onite
1
@Onite Es mucho más tarde ahora y estoy usando AS 1.5 pero no sabía sobre la funcionalidad agregada -end y -start de ng-repeat. Apuntaste allí, así que nunca te disculpes por añadir información a una respuesta
Neville
1
La url para la ng repetición de la documentación es incorrecta, pero el cambio no tiene más de seis caracteres, por lo que no puedo editarlo sin agregar una metaedición
Bill Rawlinson
35

El desarrollador de AngularJS @ igor-minar respondió esto en Angular.js ng-repeat en varios elementos .

Miško Hevery implementó recientemente el soporte adecuado a través de ng-repeat-starty ng-repeat-end. Esta mejora no se ha lanzado a partir de 1.0.7 (estable) y 1.1.5 (inestable).

Actualizar

Esto ahora está disponible en 1.2.0rc1. Echa un vistazo a los documentos oficiales y este screencast de John Lindquist.

Anson
fuente
Menciona esto en la transmisión en vivo de la reunión Angular del 11 de junio de 2013. Espero con ansias esta y otras características en Angular 1.1.5+ y Angular 2.0.
thegreenpizza
Estoy señalando el 1.1.5 en cdnjs cdn y esto no está funcionando. //cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js ¿sabes en qué versión se supone que está disponible?
Shanimal
Correcto, no se lanzó a partir de 1.1.5, así que mire 1.1.6 (o muy probablemente 1.2.0) para aterrizar pronto. Aquí está el compromiso de Miško para ver el lanzamiento: github.com/angular/angular.js/commit/…
Anson
También es bueno notar que esto funciona para todas las directivas, no solo ngRepeat;)
7hi4g0
4

Tener varios elementos puede ser válido, pero si está intentando construir una cuadrícula desplazable con encabezados / pies de página fijos, lo siguiente podría no funcionar. Este código asume los siguientes CSS, jquery y 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 construir encabezado / pie de página fijo para la cuadrícula de la tabla desplazable

#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 unir el desplazamiento horizontal de tbody, esto no funciona porque tbody se repite durante ng-repeat.

$(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
fuente
0

Puede hacerlo de esta manera, como lo mostré en esta respuesta: 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
fuente