tutorial ejemplos descargar javascript angularjs

javascript - ejemplos - angularjs tutorial



Agregando filas con ng-repeat y bucle anidado (6)

Estoy buscando una manera de agregar filas a una tabla. Mi estructura de datos se ve así:

rows = [ { name : ''row1'', subrows : [{ name : ''row1.1'' }, { name : ''row1.2'' }] }, { name : ''row2'' } ];

Quiero crear una tabla que se vea así:

table row1 row1.1 row1.2 row2

¿Es eso posible con js ng-repetición angular? Si no, ¿cuál sería una forma "angular" de hacer eso?

Edición: Acoplar la matriz sería una mala solución porque si puedo iterar sobre los subelementos, podría usar diferentes etiquetas html dentro de las celdas, otras clases de css, etc.


Aquí hay un ejemplo. Este código imprime todos los nombres de todas las personas dentro de la matriz peopeByCity .

TS:

export class AppComponent { peopleByCity = [ { city: ''Miami'', people: [ { name: ''John'', age: 12 }, { name: ''Angel'', age: 22 } ] }, { city: ''Sao Paulo'', people: [ { name: ''Anderson'', age: 35 }, { name: ''Felipe'', age: 36 } ] } ] }

HTML:

<div *ngFor="let personsByCity of peopleByCity"> <div *ngFor="let person of personsByCity.people"> {{ person.name }} </div> </div>


Estoy un poco sorprendido de que tantos estén defendiendo directivas personalizadas y creando variables de proxy actualizadas por $ watch.

¡Problemas como este son la razón por la que se hicieron los filtros AngularJS!

De la documentación:

A filter formats the value of an expression for display to the user.

No buscamos manipular los datos, simplemente formatéelos para mostrarlos de otra manera. Así que hagamos un filtro que tome nuestra matriz de filas, la aplane y devuelva las filas aplanadas.

.filter(''flattenRows'', function(){ return function(rows) { var flatten = []; angular.forEach(rows, function(row){ subrows = row.subrows; flatten.push(row); if(subrows){ angular.forEach(subrows, function(subrow){ flatten.push( angular.extend(subrow, {subrow: true}) ); }); } }); return flatten; } })

Ahora todo lo que necesitamos es agregar el filtro a ngRepeat:

<table class="table table-striped table-hover table-bordered"> <thead> <tr> <th>Rows with filter</th> </tr> </thead> <tbody> <tr ng-repeat="row in rows | flattenRows"> <td>{{row.name}}</td> </tr> </tbody> </table>

Ahora puede combinar su tabla con otros filtros si lo desea, como una búsqueda.

Si bien el enfoque de múltiples tbody es práctico y válido, desordenará cualquier CSS que se base en el orden o el índice de las filas secundarias, como una tabla "a rayas" y también supone que no ha diseñado su cuerpo en un Manera que no quieres repetir.

Aquí hay un plunk: http://embed.plnkr.co/otjeQv7z0rifPusneJ0F/preview

Edición: agregué un valor de subrow y lo usé en la tabla para mostrar qué filas son subrows, ya que usted indicó una preocupación por poder hacer eso.


Más de 3 años después, he estado enfrentando el mismo problema y, antes de escribir una directiva, probé esto y me funcionó bien:

<table> <tbody> <tr ng-repeat-start="row in rows"> <td> {{ row.name }} </td> </tr> <tr ng-repeat-end ng-repeat="subrow in row.subrows"> <td> {{ subrow.name }} </td> </tr> </tbody> </table>


Más de un año después, pero encontró una solución alternativa, al menos para dos niveles (padres-> hijos).
Solo repite tbody ''s

<table> <tbody ng-repeat="row in rows"> <tr> <th>{{row.name}}</th> </tr> <tr ng-repeat="sub in row.subrows"> <td>{{sub.name}}</td> </tr> </tbody> </table>

Por lo que sé, todos los navegadores admiten varios elementos tbody dentro de una tabla.


No podrá hacer esto con ng-repeat. Sin embargo, puedes hacerlo con una directiva.

<my-table rows=''rows''></my-table>

Fiddle

myApp.directive(''myTable'', function () { return { restrict: ''E'', link: function (scope, element, attrs) { var html = ''<table>''; angular.forEach(scope[attrs.rows], function (row, index) { html += ''<tr><td>'' + row.name + ''</td></tr>''; if (''subrows'' in row) { angular.forEach(row.subrows, function (subrow, index) { html += ''<tr><td>'' + subrow.name + ''</td></tr>''; }); } }); html += ''</table>''; element.replaceWith(html) } } });


Si es posible:

Controlador:

app.controller(''AppController'', [ ''$scope'', function($scope) { $scope.rows = [ { name : ''row1'', subrows : [{ name : ''row1.1'' }, { name : ''row1.2'' }] }, { name : ''row2'' } ]; } ] );

HTML:

<table> <tr ng-repeat="row in rows"> <td> {{row.name}} <table ng-show="row.subrows"> <tr ng-repeat="subrow in row.subrows"> <td>{{subrow.name}}</td> </tr> </table> </td> </tr> </table>

Plunker

En caso de que no desee sub-tablas, alise las filas (mientras anota subalternos, para poder diferenciar):

Controlador:

function($scope) { $scope.rows = [ { name : ''row1'', subrows : [{ name : ''row1.1'' }, { name : ''row1.2'' }] }, { name : ''row2'' } ]; $scope.flatten = []; var subrows; $scope.$watch(''rows'', function(rows){ var flatten = []; angular.forEach(rows, function(row){ subrows = row.subrows; delete row.subrows; flatten.push(row); if(subrows){ angular.forEach(subrows, function(subrow){ flatten.push( angular.extend(subrow, {subrow: true}) ); }); } }); $scope.flatten = flatten; }); }

HTML:

<table> <tr ng-repeat="row in flatten"> <td> {{row.name}} </td> </tr> </table>

Plunker