Angular.js ng-repeat sur plusieurs trs

125

J'utilise Angular.js pour une application qui utilise très caché pour simuler un effet de glissement en montrant le tr et en faisant glisser le div dans le td ci-dessous. Ce processus a fonctionné de manière fantastique en utilisant knockout.js lors de l'itération sur un tableau de ces lignes, car je pouvais utiliser <!-- ko:foreach -->autour des deux éléments tr.

Avec angular, ng-repeatdoit être appliqué à un élément html, ce qui signifie que je n'arrive pas à répéter ces doubles lignes en utilisant des méthodes standard. Ma première réponse à cela a été de créer une directive pour représenter ces doubles très, mais cela a échoué car les modèles de directive doivent avoir un seul élément racine, mais j'en ai deux ( <tr></tr><tr></tr>).

Si quelqu'un ayant de l'expérience avec ng-repeat et angular qui a craqué cela peut expliquer comment résoudre ce problème, je serais grandement reconnaissant.

(Je dois également noter que l'attachement ng-repeatau tbody est une option, mais cela produit plusieurs tbodys, et je suppose que c'est une mauvaise forme pour le HTML standard, bien que me corrigiez si je me trompe)

lapizza verte
la source

Réponses:

169

Utiliser ng-repeatsur tbodysemble être valide voir ce post .

De plus, un test rapide via un validateur html a permis plusieurs tbodyéléments dans le même tableau.

Mise à jour: à partir d'au moins Angular 1.2, il existe un ng-repeat-startet ng-repeat-endpour permettre de répéter une série d'éléments. Voir la documentation pour plus d'informations et merci à @Onite pour le commentaire!

Gloopy
la source
Fantastique. J'ai eu le même problème et j'ai vraiment débattu de le faire, mais je pensais que cela ne fonctionnerait jamais simplement en itérant sur la balise tbody. Merci!
KhalilRavanna
12
C'est un peu après le fait maintenant, mais Angular 1.2 a introduit les directives ng-repeat-start et ng-repeat-end pour vous permettre d'itérer sur plusieurs éléments.
Onite
1
@Onite C'est beaucoup plus tard maintenant et j'utilise AS 1.5 mais je ne connaissais pas les fonctionnalités ajoutées -end et -start de ng-repeat. Vous m'avez pointé là-bas, alors ne vous excusez jamais d'avoir ajouté des informations à une réponse.
Neville
1
L'URL de la documentation ng repeat est fausse mais le changement ne fait pas plus de six caractères, donc je ne peux pas le modifier sans simplement ajouter une méta-édition inutile. L'URL correcte devrait être docs.angularjs.org/api/ng/ directive / ngRepeat
Bill Rawlinson
35

Le développeur AngularJS @ igor-minar a répondu à cette question dans Angular.js ng-repeat sur plusieurs éléments .

Miško Hevery a récemment mis en place un support approprié via ng-repeat-startet ng-repeat-end. Cette amélioration n'a pas été publiée à partir de 1.0.7 (stable) et 1.1.5 (instable).

Mettre à jour

Ceci est maintenant disponible dans 1.2.0rc1. Consultez les documents officiels et ce screencast de John Lindquist.

Anson
la source
Il le mentionne dans le livestream de rencontre angulaire du 11 juin 2013. Dans l'attente de cette fonctionnalité et d'autres fonctionnalités dans Angular 1.1.5+ et Angular 2.0.
thegreenpizza le
Je pointe vers le 1.1.5 sur cdnjs cdn et cela ne fonctionne pas. //cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js savez-vous dans quelle version il est censé être disponible?
Shanimal
Correct, n'a pas été publié à partir de la version 1.1.5, alors regardez la version 1.1.6 (ou très probablement la 1.2.0) pour atterrir bientôt. Voici l'engagement de Miško à surveiller la sortie: github.com/angular/angular.js/commit/…
Anson
Il est également bon de noter que cela fonctionne pour toutes les directives, pas seulement ngRepeat;)
7hi4g0
4

Avoir plusieurs éléments peut être valide, mais si vous essayez de créer une grille déroulante avec des en-têtes / pieds de page fixes, la suite pourrait ne pas fonctionner. Ce code suppose les CSS, jquery et AngularJS suivants.

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 pour créer un en-tête / pied de page fixe pour une grille de tableau déroulante

#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 pour lier le défilement horizontal de tbody, cela ne fonctionne pas car tbody se répète pendant 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
la source
0

Vous pouvez le faire de cette manière, comme je l'ai montré dans cette réponse: 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
la source