Obecnie używam tego fragmentu kodu do renderowania listy:
<ul ng-cloak>
<div ng-repeat="n in list">
<li><a href="{{ n[1] }}">{{ n[0] }}</a></li>
<li class="divider"></i>
</div>
<li>Additional item</li>
</ul>
Jednak <div>
element powoduje bardzo drobne błędy renderowania w niektórych przeglądarkach. Chciałbym wiedzieć, czy istnieje sposób na wykonanie powtórzenia ng bez kontenera div lub jakaś alternatywna metoda, aby osiągnąć ten sam efekt.
javascript
css
html
angularjs
nehz
źródło
źródło
htmlAppend
dyrektywy?Odpowiedzi:
Jak powiedział Andy Joslin, pracowali nad komentarzami opartymi na powtórzeniach ng, ale najwyraźniej było zbyt wiele problemów z przeglądarką . Na szczęście AngularJS 1.2 dodaje wbudowaną obsługę powtarzania bez dodawania elementów potomnych z nowymi dyrektywami
ng-repeat-start
ing-repeat-end
.Oto mały przykład dodawania paginacji Bootstrap :
<ul class="pagination"> <li> <a href="#">«</a> </li> <li ng-repeat-start="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li> <li ng-repeat-end class="divider"></li> <li> <a href="#">»</a> </li> </ul>
Pełny przykład roboczy można znaleźć tutaj .
John Lindquist ma również samouczek wideo na swojej doskonałej stronie egghead.io .
źródło
ng-repeat-start/end
ale to jest mylący przykład i niewłaściwy przypadek użycia.ng-repeat
Należy tutaj użyć standardu , ponieważ kod renderuje dodatkowe puste miejsceli
dla każdego elementu. Powinieneś prawdopodobnie wspomnieć o tym w swoim poście.ng-repeat-start
. Dodamdivider
klasę html do mojej odpowiedzi, aby była bardziej przejrzysta.ng-repeat-start
ing-repeat-end
są trochę zagmatwane.Składnia wiązania bez kontenera KnockoutJS
Proszę o chwilę cierpliwości: KnockoutJS oferuje bardzo wygodną opcję użycia bezkontenerowej składni wiązania do
foreach
powiązania, jak omówiono w uwadze 4foreach
dokumentacji powiązań. http://knockoutjs.com/documentation/foreach-binding.htmlJak pokazuje przykład dokumentacji Knockout, możesz napisać swoje powiązanie w KnockoutJS w następujący sposób:
<ul> <li class="header">Header item</li> <!-- ko foreach: myItems --> <li>Item <span data-bind="text: $data"></span></li> <!-- /ko --> </ul>
Myślę, że to raczej niefortunne, że AngularJS nie oferuje tego typu składni.
Angular
ng-repeat-start
ing-repeat-end
W sposobie rozwiązywania
ng-repeat
problemów przez AngularJS , próbki, które napotykam, są typu jmagnusson zamieszczonego w jego (pomocnej) odpowiedzi.<li ng-repeat-start="page in [1,2,3,4,5]"><a href="#">{{page}}</a></li> <li ng-repeat-end></li>
Moja pierwotna myśl po zobaczeniu tej składni brzmi: naprawdę? Dlaczego Angular wymusza te wszystkie dodatkowe znaczniki, z którymi nie chcę mieć nic wspólnego, a to jest o wiele łatwiejsze w Knockout? Ale potem komentarz hitautodestruct w odpowiedzi jmagnusson zaczął mnie zastanawiać: co jest generowane przez ng-repeat-start i ng-repeat-end w oddzielnych tagach?
Czystszy sposób używania
ng-repeat-start
ing-repeat-end
Po zbadaniu twierdzenia hitautodestruct dodanie
ng-repeat-end
do oddzielnego tagu jest dokładnie tym, czego nie chciałbym robić w większości przypadków, ponieważ generuje całkowicie bezużyteczne elementy: w tym przypadku<li>
elementy, w których nic nie ma. Lista podzielona na strony w Bootstrap 3 stylizuje elementy listy w taki sposób, że wygląda na to, że nie wygenerowałeś żadnych zbędnych elementów, ale kiedy sprawdzasz wygenerowany kod HTML, są one tam.Na szczęście nie trzeba wiele robić, aby mieć czystsze rozwiązanie i mniejszą ilość html: wystarczy umieścić
ng-repeat-end
deklarację na tym samym tagu html, który ma rozszerzenieng-repeat-start
.<ul class="pagination"> <li> <a href="#">«</a> </li> <li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li> <li> <a href="#">»</a> </li> </ul>
Daje to 3 korzyści:
ng-repeat
nie zostanie wygenerowany, co daje taką samą korzyść, jaką daje w tym przypadku bezkontenerowe wiązanie KnockoutaAle jest jeszcze czystszy sposób
Po dokładniejszym przejrzeniu komentarzy na githubie dotyczących tego problemu dla Angular, https://github.com/angular/angular.js/issues/1891 ,
nie musisz używać
ng-repeat-start
ing-repeat-end
osiągać tych samych korzyści. Zamiast tego, ponownie rozwidlając przykład jmagnusson, możemy po prostu:<ul class="pagination"> <li> <a href="#">«</a> </li> <li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li> <li> <a href="#">»</a> </li> </ul>
Kiedy więc używać
ng-repeat-start
ing-repeat-end
? Zgodnie z dokumentacją kątową , doDość gadania, pokaż kilka przykładów!
Słusznie; ten plik jsbin omawia pięć przykładów tego, co się dzieje, gdy to robisz, a kiedy nie używasz
ng-repeat-end
tego samego tagu.http://jsbin.com/eXaPibI/1/
źródło
ng-repeat-start
ing-repeat-end
do tego samego elementu jest całkowicie bezużyteczne, gdy możesz użyć wartości domyślnej angularng-repeat
i skończyć z tym.ng-repeat
lub znalezienie alternatywy dla użycia OP,ng-repeat
która wyeliminujediv
artefakt w HTML. Twoja odpowiedź tego nie robi, ponieważ nie ma sposobu, aby użyć jej dla dwóchli
elementów w pytaniu. Jeśli się mylę, podaj przykładowe znaczniki, które dostosowują kod OP w celu wyeliminowaniadiv
elementu.li
został wygenerowany elementli
dzielący , czyli dodatkowy, który widzisz w swoim jsbin.ngRepeat może nie wystarczyć, ale można to połączyć z niestandardową dyrektywą. Możesz delegować zadanie dodawania elementów rozdzielających do kodu, jeśli nie masz nic przeciwko odrobinie jQuery.
<li ng-repeat="item in coll" so-add-divide="your exp here"></li>
Taka prosta dyrektywa tak naprawdę nie potrzebuje wartości atrybutu, ale może dać ci wiele możliwości, takich jak warunkowe dodanie dzielnika według indeksu, długości itp. Lub coś zupełnie innego.
źródło
Niedawno miałem ten sam problem polegający na tym, że musiałem powtórzyć dowolną kolekcję przęseł i obrazów - posiadanie elementu wokół nich nie wchodziło w grę - jest jednak proste rozwiązanie, jednak stwórz dyrektywę „null”:
app.directive("diNull", function() { return { restrict: "E", replace: true, template: "" }; });
Następnie możesz użyć powtórzenia dla tego elementu, gdzie element.url wskazuje na szablon dla tego elementu:
<di-null ng-repeat="element in elements" ng-include="element.url" ></di-null>
Spowoduje to powtórzenie dowolnej liczby różnych szablonów bez żadnego kontenera wokół nich
Uwaga: hmm, mógłbym przysiąc, że to usunęło element di-null podczas renderowania, ale ponowne sprawdzenie tego nie ... nadal rozwiązało moje problemy z układem ... ciekawość i ciekawość ...
źródło
replace
jest przestarzałe od wersji 2.0.Istnieje ograniczenie dyrektywy komentarza, ale ngRepeat go nie obsługuje (ponieważ potrzebuje elementu do powtórzenia).
Myślę, że widziałem, jak zespół Angular powiedział, że będzie pracował nad komentarzami ng-powtórzeń, ale nie jestem pewien. Powinieneś otworzyć problem w repozytorium. http://github.com/angular/angular.js
źródło
Nie ma magicznego sposobu Angulara, aby to zrobić, w twoim przypadku możesz to zrobić, aby uzyskać prawidłowy HTML, jeśli używasz Bootstrap. Wtedy uzyskasz taki sam efekt, jak dodanie rozdzielacza li
Utwórz zajęcia:
span.divider { display: block; }
Teraz zmień swój kod na ten:
<ul ng-cloak> <li div ng-repeat="n in list"> <a href="{{ n[1] }}">{{ n[0] }}</a> <span class="divider"></span> </li> <li>Additional item</li> </ul>
źródło
za rozwiązanie, które naprawdę działa
html
<remove ng-repeat-start="itemGroup in Groups" ></remove> html stuff in here including inner repeating loops if you want <remove ng-repeat-end></remove>
dodaj dyrektywę angular.js.
//remove directive (function(){ var remove = function(){ return { restrict: "E", replace: true, link: function(scope, element, attrs, controller){ element.replaceWith('<!--removed element-->'); } }; }; var module = angular.module("app" ); module.directive('remove', [remove]); }());
na krótkie wyjaśnienie,
ng-repeat wiąże się z
<remove>
elementem i zapętla się tak, jak powinno, a ponieważ użyliśmy ng-repeat-start / ng-repeat-end, zapętla blok html, a nie tylko element.następnie niestandardowa dyrektywa remove umieszcza elementy
<remove>
początkowe i końcowe za pomocą<!--removed element-->
źródło
replaceWith(...)
pokazują, że węzeł tekstowy nie jest komentarzem. Odkryłem, że używam tylkoelement.remove()
prac.