Angular.js ng-repeat über mehrere trs

125

Ich verwende Angular.js für eine Anwendung, die versteckte trs verwendet, um einen Rutscheffekt zu simulieren, indem ich das tr zeige und das div im td unten nach unten rutsche. Dieser Prozess funktionierte fantastisch mit knockout.js, wenn ich über ein Array dieser Zeilen iterierte, da ich <!-- ko:foreach -->beide tr-Elemente verwenden konnte.

Mit Angular ng-repeatmuss auf ein HTML-Element angewendet werden, was bedeutet, dass ich diese doppelten Zeilen nicht mit Standardmethoden wiederholen kann. Meine erste Antwort darauf war, eine Direktive zu erstellen, um diese doppelten trs darzustellen, aber das war zu kurz, weil Direktivenvorlagen ein einziges Stammelement haben müssen, aber ich habe zwei ( <tr></tr><tr></tr>).

Wenn jemand mit Erfahrung mit ng-repeat und eckig, der dies geknackt hat, erklären kann, wie dieses Problem gelöst werden kann, wäre ich sehr dankbar.

(Ich sollte auch beachten, dass das Anhängen ng-repeatan den tbody eine Option ist, aber dies erzeugt mehrere tbodys, und ich gehe davon aus, dass dies eine schlechte Form für Standard-HTML ist, obwohl ich korrigiert werde, wenn ich falsch liege.)

thegreenpizza
quelle

Antworten:

168

Die Verwendung von ng-repeaton tbodyscheint gültig zu sein, siehe diesen Beitrag .

Auch ein schneller Test durch einen HTML-Validator erlaubte mehrere tbodyElemente in derselben Tabelle.

Update: Ab mindestens Angular 1.2 gibt es ein ng-repeat-startund ng-repeat-end, um das Wiederholen einer Reihe von Elementen zu ermöglichen. Weitere Informationen finden Sie in der Dokumentation. Vielen Dank an @Onite für den Kommentar!

Gloopy
quelle
Fantastisch. Ich hatte das gleiche Problem und diskutierte tatsächlich darüber, aber ich dachte, es würde niemals funktionieren, wenn ich nur auf dem tbody-Tag iteriere. Vielen Dank!
KhalilRavanna
11
Es ist jetzt ein bisschen nachträglich, aber Angular 1.2 hat die Anweisungen ng-repeat-start und ng-repeat-end eingeführt, damit Sie über mehrere Elemente iterieren können.
Onite
1
@Onite Es ist jetzt viel später und ich verwende AS 1.5, wusste aber nichts über die zusätzlichen Funktionen -end und -start von ng-repeat. Sie haben mich dort gezeigt, also entschuldigen Sie sich nie dafür, dass Sie einer Antwort Informationen hinzugefügt haben.
Neville
1
Die URL für die ng-Wiederholungsdokumentation ist falsch, aber die Änderung besteht nicht aus mehr als sechs Zeichen. Daher
Bill Rawlinson
35

AngularJS-Entwickler @ igor-minar hat dies in Angular.js ng-repeat über mehrere Elemente hinweg beantwortet .

Miško Hevery hat kürzlich eine angemessene Unterstützung über ng-repeat-startund implementiert ng-repeat-end. Diese Verbesserung wurde ab 1.0.7 (stabil) und 1.1.5 (instabil) nicht veröffentlicht.

Aktualisieren

Dies ist jetzt in 1.2.0rc1 verfügbar. Schauen Sie sich die offiziellen Dokumente und diesen Screencast von John Lindquist an.

Anson
quelle
Er erwähnt dies im Livestream des Angular-Meetups vom 11. Juni 2013. Er freut sich auf diese und andere Funktionen in Angular 1.1.5+ und Angular 2.0.
Thegreenpizza
Ich zeige auf 1.1.5 auf cdnjs cdn und das funktioniert nicht. //cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js wissen Sie, in welcher Version dies verfügbar sein soll?
Shanimal
Richtig, wurde ab 1.1.5 nicht veröffentlicht. Sehen Sie sich also an, dass 1.1.6 (oder sehr wahrscheinlich 1.2.0) bald landet. Hier ist Miškos Zusage, auf die Veröffentlichung zu achten
Anson
Es ist auch gut zu bemerken, dass dies für jede Direktive funktioniert, nicht nur für ngRepeat;)
7hi4g0
4

Das Vorhandensein mehrerer Elemente ist möglicherweise gültig. Wenn Sie jedoch versuchen, ein scrollbares Raster mit festen Kopf- / Fußzeilen zu erstellen, funktioniert das Folgende möglicherweise nicht. Dieser Code setzt das folgende CSS, jquery und AngularJS voraus.

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 zum Erstellen einer festen Kopf- / Fußzeile für ein scrollbares Tabellenraster

#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}

Um das horizontale Scrollen von tbody zu binden, funktioniert dies nicht, da sich tbody während ng-repeat wiederholt.

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

Sie können dies auf diese Weise tun, wie ich in dieser Antwort gezeigt habe: 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
quelle