index example bootstrap array javascript html css html5 angularjs

javascript - example - ng-< repeat angular



AngularJS ng-repeat sin elemento html (6)

Sintaxis de enlace sin contenedor KnockoutJS

Tenga paciencia conmigo: KnockoutJS ofrece una opción ultra conveniente de usar una sintaxis de enlace sin contenedor para su enlace foreach como se analiza en la Nota 4 de la documentación de enlace foreach . http://knockoutjs.com/documentation/foreach-binding.html

Como lo ilustra el ejemplo de documentación de Knockout, puede escribir su enlace en KnockoutJS de esta manera:

<ul> <li class="header">Header item</li> <!-- ko foreach: myItems --> <li>Item <span data-bind="text: $data"></span></li> <!-- /ko --> </ul>

Creo que es desafortunado que AngularJS no ofrezca este tipo de sintaxis.

Angular''s ng-repeat-start y ng-repeat-end

En la forma AngularJS para resolver problemas de ng-repeat , las muestras que encuentro son del tipo jmagnusson publicadas en su respuesta (útil).

<li ng-repeat-start="page in [1,2,3,4,5]"><a href="#">{{page}}</a></li> <li ng-repeat-end></li>

Mi pensamiento original al ver esta sintaxis es: ¿en serio? ¿Por qué Angular fuerza todo este marcado extra con el que no quiero hacer nada y que es mucho más fácil en Knockout? Pero luego el comentario de hitautodestruct en la respuesta de jmagnusson comenzó a hacerme preguntar: ¿qué se está generando con ng-repeat-start y ng-repeat-end en etiquetas separadas?

Una forma más limpia de usar ng-repeat-start y ng-repeat-end

Tras la investigación de la aserción de hitautodestruct, agregar ng-repeat-end a una etiqueta separada es exactamente lo que no quisiera hacer en la mayoría de los casos, porque genera elementos completamente inútiles: en este caso, elementos <li> sin nada en ellos. La lista paginada de Bootstrap 3 estiliza los elementos de la lista para que parezca que no generó ningún elemento superfluo, pero cuando inspecciona el html generado, están allí.

Afortunadamente , no necesita hacer mucho para tener una solución más limpia y una cantidad más pequeña de html: simplemente ponga la declaración ng-repeat-end en la misma etiqueta html que tiene el ng-repeat-start .

<ul class="pagination"> <li> <a href="#">&laquo;</a> </li> <li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li> <li> <a href="#">&raquo;</a> </li> </ul>

Esto le da 3 ventajas:

  1. menos etiquetas html para escribir
  2. las etiquetas vacías e inútiles no son generadas por Angular
  3. cuando la matriz para repetir está vacía, la etiqueta con ng-repeat no se generará, lo que le da la misma ventaja que la vinculación sin contenedor de Knockout le brinda a este respecto

Pero todavía hay una manera más limpia

Después de revisar los comentarios en github sobre este tema para Angular, https://github.com/angular/angular.js/issues/1891 ,
no necesita usar ng-repeat-start y ng-repeat-end para lograr las mismas ventajas. En cambio, volviendo a bifurcar el ejemplo de jmagnusson, podemos ir:

<ul class="pagination"> <li> <a href="#">&laquo;</a> </li> <li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li> <li> <a href="#">&raquo;</a> </li> </ul>

Entonces, ¿cuándo usar ng-repeat-start y ng-repeat-end ? Según la documentación angular , para

... repite una serie de elementos en lugar de solo un elemento principal ...

¡Habla lo suficiente, muestra algunos ejemplos!

Lo suficientemente justo; este jsbin repasa cinco ejemplos de lo que sucede cuando lo haces y cuando no usas ng-repeat-end en la misma etiqueta.

http://jsbin.com/eXaPibI/1/

Actualmente estoy usando este fragmento de código para hacer una lista:

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

Sin embargo, el elemento <div> está causando algunos defectos de representación muy menores en algunos navegadores. Me gustaría saber si hay alguna manera de hacer ng-repeat sin el contenedor div o algún otro método alternativo para lograr el mismo efecto.


Como Andy Joslin dijo que estaban trabajando en ng-repeats basados ​​en comentarios, pero aparentemente había demasiados problemas con el navegador . Afortunadamente AngularJS 1.2 agrega soporte incorporado para repetir sin agregar elementos secundarios con las nuevas directivas ng-repeat-start y ng-repeat-end .

Aquí hay un pequeño ejemplo para agregar la paginación de Bootstrap :

<ul class="pagination"> <li> <a href="#">&laquo;</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="#">&raquo;</a> </li> </ul>

Un ejemplo completo de trabajo se puede encontrar here .

John Lindquist también tiene un video tutorial de esto en su excelente página de egghead.io .


Hace poco tuve el mismo problema porque tuve que repetir una colección arbitraria de luces e imágenes (tener un elemento a su alrededor no era una opción). Sin embargo, hay una solución simple: crear una directiva "nula":

app.directive("diNull", function() { return { restrict: "E", replace: true, template: "" }; });

Luego puede usar una repetición en ese Elemento, donde element.url apunta a la plantilla para ese elemento:

<di-null ng-repeat="element in elements" ng-include="element.url" ></di-null>

Esto repetirá cualquier número de plantillas diferentes sin contenedor a su alrededor

Nota: hmm, podría haber jurado que esto eliminó el elemento di-null cuando lo renderice, pero revisarlo de nuevo no ... aún así resolvió mis problemas de diseño ... curioso y curioso ...


Hay una restricción de directiva de comentarios, pero ngRepeat no la admite (ya que necesita un elemento para repetir).

Creo que vi al equipo angular decir que trabajarían en comentar ng-repeats, pero no estoy seguro. Debería abrir un problema en el repositorio. http://github.com/angular/angular.js


No existe una forma mágica angular para hacer esto, para su caso puede hacerlo, para obtener HTML válido, si está utilizando Bootstrap. Entonces obtendrá el mismo efecto que agregar el li.divider

Crear una clase:

span.divider { display: block; }

Ahora cambie su código a esto:

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


ngRepeat puede no ser suficiente, sin embargo, puede combinar eso con una directiva personalizada. Puedes delegar la tarea de agregar elementos divisores al código si no te importa un poco jQuery.

<li ng-repeat="item in coll" so-add-divide="your exp here"></li>

Una directiva tan simple en realidad no necesita un valor de atributo, pero podría darle muchas posibilidades, como agregar condicionalmente un divisor de acuerdo con el índice, la longitud, etc. o algo completamente diferente.