В настоящее время я использую этот фрагмент кода для отображения списка:
<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>
Однако этот <div>
элемент вызывает некоторые очень незначительные дефекты рендеринга в некоторых браузерах. Я хотел бы знать, есть ли способ выполнить ng-repeat без контейнера div или какой-либо альтернативный метод для достижения того же эффекта.
javascript
css
html
angularjs
nehz
источник
источник
htmlAppend
директиву?Ответы:
Как сказал Энди Джослин, они работали над ng-повторами на основе комментариев, но, по-видимому, было слишком много проблем с браузером . К счастью, AngularJS 1.2 добавляет встроенную поддержку повторения без добавления дочерних элементов с новыми директивами
ng-repeat-start
иng-repeat-end
.Вот небольшой пример добавления разбивки на страницы в 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>
Полный рабочий пример можно найти здесь .
У Джона Линдквиста также есть видеоурок по этому поводу на его превосходной странице egghead.io .
источник
ng-repeat-start/end
но это запутанный пример и неправильный вариант его использования. Здесьng-repeat
следует использовать стандарт, так как ваш код отображает дополнительный пустойli
для каждого элемента. Вероятно, вам стоит упомянуть об этом в своем сообщении.ng-repeat-start
. Я добавлюdivider
к своему ответу класс html, чтобы было понятнее.ng-repeat-start
иng-repeat-end
немного сбивают с толку. Документация Angular помогает: https://docs.angularjs.org/api/ng/directive/ngRepeat#special-repeat-start-and-end-pointsСинтаксис бесконтейнерной привязки KnockoutJS
Потерпите секунду: KnockoutJS предлагает ультра-удобный вариант использования синтаксиса привязки без контейнера для его
foreach
привязки, как описано в примечании 4foreach
документации привязки. http://knockoutjs.com/documentation/foreach-binding.htmlКак показывает пример документации Knockout, вы можете написать свою привязку в KnockoutJS следующим образом:
<ul> <li class="header">Header item</li> <!-- ko foreach: myItems --> <li>Item <span data-bind="text: $data"></span></li> <!-- /ko --> </ul>
Мне очень жаль, что AngularJS не предлагает такого синтаксиса.
Angular's
ng-repeat-start
иng-repeat-end
В способе решения
ng-repeat
проблем AngularJS образцы, с которыми я сталкиваюсь, относятся к типу jmagnusson, опубликованному в его (полезном) ответе.<li ng-repeat-start="page in [1,2,3,4,5]"><a href="#">{{page}}</a></li> <li ng-repeat-end></li>
Моя первоначальная мысль, увидев этот синтаксис, такова: действительно? Почему Angular заставляет всю эту дополнительную разметку, с которой я не хочу иметь ничего общего, и это намного проще в Knockout? Но затем комментарий hitautodestruct в ответе jmagnusson заставил меня задуматься: что создается с помощью ng-repeat-start и ng-repeat-end в отдельных тегах?
Более чистый способ использования
ng-repeat-start
иng-repeat-end
После исследования утверждения hitautodestruct, добавление
ng-repeat-end
в отдельный тег - это именно то, что я бы не хотел делать в большинстве случаев, потому что он генерирует совершенно бесполезные элементы: в данном случае<li>
элементы, в которых ничего нет. Разбитый на страницы список Bootstrap 3 стилизует элементы списка так, чтобы казалось, что вы не сгенерировали никаких лишних элементов, но когда вы проверяете сгенерированный html, они есть.К счастью , вам не нужно много делать, чтобы получить более чистое решение и меньшее количество html: просто поместите
ng-repeat-end
объявление в тот же тег html с расширениемng-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>
Это дает 3 преимущества:
ng-repeat
не будет сгенерирован, что дает вам то же преимущество, что бесконтейнерная привязка Knockout дает вам в этом отношенииНо есть еще более чистый способ
После дальнейшего изучения комментариев в github по этой проблеме для Angular, https://github.com/angular/angular.js/issues/1891 ,
вам не нужно использовать
ng-repeat-start
иng-repeat-end
для достижения тех же преимуществ. Вместо этого, снова разветвляя пример jmagnusson, мы можем просто пойти:<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>
Итак, когда использовать
ng-repeat-start
иng-repeat-end
? Согласно документации angular , чтобыХватит говорить, покажи примеры!
Справедливо; Этот jsbin рассматривает пять примеров того, что происходит, когда вы используете и когда не используете один и
ng-repeat-end
тот же тег.http://jsbin.com/eXaPibI/1/
источник
ng-repeat-start
иng-repeat-end
к одному и тому же элементу совершенно бесполезно, если вы можете использовать значение по умолчанию для angularng-repeat
и покончить с этим.ng-repeat
или найти альтернативу использованию OP,ng-repeat
которая устраняетdiv
артефакт в HTML. Ваш ответ этого не делает, так как его нельзя использовать для двухli
элементов вопроса. Если я ошибаюсь, предоставьте образец разметки, которая адаптирует код OP для устраненияdiv
элемента.li
был сгенерирован разделитель , которыйli
вы видите в своем jsbin.ngRepeat может быть недостаточно, однако вы можете комбинировать это с настраиваемой директивой. Вы можете делегировать задачу добавления элементов-разделителей в код, если не возражаете против использования jQuery.
<li ng-repeat="item in coll" so-add-divide="your exp here"></li>
Такая простая директива на самом деле не требует значения атрибута, но может дать вам множество возможностей, например, условное добавление разделителя в соответствии с индексом, длиной и т. Д. Или что-то совершенно другое.
источник
Недавно у меня была такая же проблема, когда мне пришлось повторить произвольный набор промежутков и изображений - наличие элемента вокруг них не было вариантом - однако есть простое решение, создать "нулевую" директиву:
app.directive("diNull", function() { return { restrict: "E", replace: true, template: "" }; });
Затем вы можете использовать повторение для этого элемента, где element.url указывает на шаблон для этого элемента:
<di-null ng-repeat="element in elements" ng-include="element.url" ></di-null>
Это будет повторять любое количество разных шаблонов без контейнера вокруг них.
Примечание: хм, я мог поклясться вслепую, что это удалило элемент di-null при рендеринге, но проверка его снова не ... все же решила мои проблемы с макетом ...
источник
replace
устарело с 2.0.Есть ограничение директивы comment, но ngRepeat его не поддерживает (так как ему нужен повторяющийся элемент).
Думаю, я видел, как команда angular говорила, что они будут работать над ng-повторами комментариев, но я не уверен. Вы должны открыть выпуск по нему на репо. http://github.com/angular/angular.js
источник
Нет никакого волшебного способа Angular сделать это, в вашем случае вы можете это сделать, чтобы получить действительный HTML, если вы используете Bootstrap. Тогда вы получите тот же эффект, что и добавление разделителя li.
Создайте класс:
span.divider { display: block; }
Теперь измените свой код на этот:
<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>
источник
для решения, которое действительно работает
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>
добавить директиву 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]); }());
для краткого объяснения,
ng-repeat привязывается к
<remove>
элементу и зацикливается так, как должно, и поскольку мы использовали ng-repeat-start / ng-repeat-end, он зацикливает блок HTML, а не только элемент.затем настраиваемая директива remove помещает
<remove>
элементы start и finish с<!--removed element-->
источник
replaceWith(...)
результатах тестирования текстовый узел не является комментарием. Я нашел просто с помощьюelement.remove()
работ.