Ich muss ng-repeat
(in AngularJS) verwenden, um alle Elemente in einem Array aufzulisten.
Die Komplikation besteht darin, dass jedes Element des Arrays in eine, zwei oder drei Zeilen einer Tabelle umgewandelt wird.
Ich kann kein gültiges HTML erstellen, wenn ng-repeat
es für ein Element verwendet wird, da zwischen <tbody>
und kein Typ eines sich wiederholenden Elements zulässig ist <tr>
.
Wenn ich zum Beispiel ng-repeat on verwenden <span>
würde, würde ich Folgendes erhalten:
<table>
<tbody>
<span>
<tr>...</tr>
</span>
<span>
<tr>...</tr>
<tr>...</tr>
<tr>...</tr>
</span>
<span>
<tr>...</tr>
<tr>...</tr>
</span>
</tbody>
</table>
Welches ist ungültig HTML.
Aber was ich generiert werden muss, ist:
<table>
<tbody>
<tr>...</tr>
<tr>...</tr>
<tr>...</tr>
<tr>...</tr>
<tr>...</tr>
<tr>...</tr>
</tbody>
</table>
Dabei wurde die erste Zeile vom ersten Array-Element generiert, die nächsten drei vom zweiten und die fünfte und sechste vom letzten Array-Element.
Wie kann ich ng-repeat so verwenden, dass das HTML-Element, an das es gebunden ist, beim Rendern "verschwindet"?
Oder gibt es dafür eine andere Lösung?
Klarstellung: Die generierte Struktur sollte wie folgt aussehen. Jedes Array-Element kann zwischen 1-3 Zeilen der Tabelle generieren. Die Antwort sollte idealerweise 0-n Zeilen pro Array-Element unterstützen.
<table>
<tbody>
<!-- array element 0 -->
<tr>
<td>One row item</td>
</tr>
<!-- array element 1 -->
<tr>
<td>Three row item</td>
</tr>
<tr>
<td>Some product details</td>
</tr>
<tr>
<td>Customer ratings</td>
</tr>
<!-- array element 2 -->
<tr>
<td>Two row item</td>
</tr>
<tr>
<td>Full description</td>
</tr>
</tbody>
</table>
tr
würde, würde ich, soweit ich weiß, eine Zeile pro Array-Element erhalten.tr
s, die von einem Array-Element erzeugt werden, haben nicht die gleiche Struktur.Antworten:
Update: Wenn Sie Angular 1.2+ verwenden, verwenden Sie ng-repeat-start . Siehe @ jmagnussons Antwort.
Ansonsten, wie wäre es, wenn Sie die ng-Wiederholung auf tbody setzen? (AFAIK, es ist in Ordnung, mehrere <tbody> s in einer einzigen Tabelle zu haben.)
quelle
Ab AngularJS 1.2 gibt es eine Direktive namens
ng-repeat-start
, die genau das tut, wonach Sie fragen. In meiner Antwort in dieser Frage finden Sie eine Beschreibung der Verwendung.quelle
Wenn Sie ng> 1.2 verwenden, finden Sie hier ein Beispiel für die Verwendung,
ng-repeat-start/end
ohne unnötige Tags zu generieren:Der wichtige Punkt: für Tags, die für verwendet
ng-repeat-start
undng-repeat-end
festgelegt werdenng-if="0"
, damit sie nicht in die Seite eingefügt werden. Auf diese Weise wird der innere Inhalt genauso behandelt wie in knockoutjs (mit Befehlen in<!--...-->
), und es entsteht kein Müll.quelle
Möglicherweise möchten Sie die Daten in Ihrem Controller reduzieren:
Und dann im HTML:
quelle
ng-repeat-start
,ng-repeat-end
Brechen mein Design, so dass die Lösung eine zusätzliche Variable Hinzufügen dieser Separator Objekt vor jedem Element und Iterierte das neue var zu schaffen war:<div class="c477_group"> <div class="c477_group_item" ng-repeat="item in itemsWithSeparator" ng-switch="item.id" ng-class="{'-divider' : item.id == 'SEPARATOR'}"> <div class="c478" ng-switch-when="FAS"/> <div class="c478" ng-switch-when="SEPARATOR" /> <div class="c479" ng-switch-default /> </div> </div>
Das Obige ist richtig, aber für eine allgemeinere Antwort reicht es nicht aus. Ich musste ng-repeat verschachteln, aber auf derselben HTML-Ebene bleiben, was bedeutet, dass ich die Elemente in dasselbe übergeordnete Element schreibe. Das Tags-Array enthält Tags, die auch ein Tags-Array haben. Es ist eigentlich ein Baum.
Also hier ist, was ich schließlich getan habe.
Beachten Sie das ng-if = "false", das die Start- und End-Divs verbirgt.
Es sollte gedruckt werden
name1, name1_1, name1_2, name2, name2_1, name2_2,
quelle
Ich möchte nur einen Kommentar abgeben, aber mein Ruf fehlt immer noch. Also füge ich eine weitere Lösung hinzu, die das Problem ebenfalls löst. Ich möchte die Aussage von @bmoeskau wirklich widerlegen, dass die Lösung dieses Problems eine "bestenfalls hackige" Lösung erfordert, und da dies kürzlich in einer Diskussion auftauchte, obwohl dieser Beitrag 2 Jahre alt ist, möchte ich meine hinzufügen besitzen zwei Cent:
Wie @btford hervorgehoben hat, scheinen Sie zu versuchen, eine rekursive Struktur in eine Liste umzuwandeln. Daher sollten Sie diese Struktur zuerst in eine Liste reduzieren. Seine Lösung macht das, aber es gibt eine Meinung, dass das Aufrufen der Funktion in der Vorlage unelegant ist. Wenn das wahr ist (ehrlich gesagt, ich weiß es nicht), würde das nicht nur die Ausführung der Funktion in der Steuerung und nicht der Direktive erfordern?
In beiden Fällen benötigt Ihr HTML eine Liste, sodass der Bereich, in dem es gerendert wird, über diese Liste verfügen sollte. Sie müssen lediglich die Struktur in Ihrem Controller reduzieren. Sobald Sie ein $ scope.rows-Array haben, können Sie die Tabelle mit einer einzigen einfachen ng-Wiederholung generieren. Kein Hacken, keine Uneleganz, einfach so, wie es funktionieren soll.
Angulars-Direktiven mangelt es nicht an Funktionalität. Sie zwingen Sie einfach, gültiges HTML zu schreiben. Ein Kollege von mir hatte ein ähnliches Problem und zitierte @bmoeskau zur Unterstützung der Kritik an Vorlagen- / Rendering-Funktionen für Winkel. Als er sich das genaue Problem ansah, stellte sich heraus, dass er einfach ein Open-Tag generieren wollte, dann ein Close-Tag woanders usw. Genau wie in den guten alten Zeiten, als wir unser HTML aus Strings zusammenlegten. Richtig? Nein.
Hier ist eine andere Lösung, um die Struktur in eine Liste zu reduzieren:
Dies funktioniert für jede baumartige Struktur mit Unterelementen. Wenn Sie das gesamte Element anstelle einer Eigenschaft möchten, können Sie die Abflachungsfunktion noch weiter verkürzen.
hoffentlich hilft das.
quelle
für eine Lösung, die wirklich funktioniert
html
Fügen Sie eine angle.js-Direktive hinzu
für eine kurze Erklärung,
ng-repeat bindet sich an das
<remove>
Element und schleift es wie es sollte, und da wir ng-repeat-start / ng-repeat-end verwendet haben, schleift es einen HTML-Block, nicht nur ein Element.Anschließend platziert die benutzerdefinierte Direktive zum Entfernen die
<remove>
Start- und Endelemente mit<!--removed element-->
quelle
Ich denke das ist gültig :)
quelle