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)

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.


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.


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));

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>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.