2012-09-20 50 views
22

Estoy tratando de insertar datos de un modelo en una plantilla, pero quiero agregar una nueva fila de tabla después de cada 7 repeticiones. Con plantillas basadas en strings, podría hacerlo bastante fácilmente usando el índice de iteración y el módulo, pero no puedo entender cómo hacerlo usando las plantillas DOM de angular.Usando ng-repeat con filas de tabla

Aquí está el código HTML:

<div ng-controller="MyCtrl"> 
    <table cellspacing="0" cellpadding="0"> 
    <colgroup span="7"></colgroup> 

    <tbody> 
    <tr class="days"> 
     <th scope="col" title="Monday">Mon</th> 
     <th scope="col" title="Tuesday">Tue</th> 
     <th scope="col" title="Wednesday">Wed</th> 
     <th scope="col" title="Thursday">Thu</th> 
     <th scope="col" title="Friday">Fri</th> 
     <th scope="col" title="Saturday">Sat</th> 
     <th scope="col" title="Sunday">Sun</th> 
    </tr> 
    <tr> 
     <td ng-repeat="date in dates"> 
      {{ date }} 
      <!-- After seven iterations a new `<tr>` should be aded --> 
     </td> 
    </tr> 
</tbody> 
</table> 
</div> 

Y el javascript, algo así como:

myApp = this.angular.module('myApp', []); 

var monthDays = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1516, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]; 

myApp.controller('MyCtrl', function($scope) { 
    return $scope.dates = monthDays; 
});​ 

Usted puede ver el código en un jsFiddle aquí: http://jsfiddle.net/3zhbB/2/

Respuesta

26

Hacer $scope.dates una matriz de matrices con los días.

Cada matriz dentro de ella hay una fila, y cada día en el interior de la matriz de la fila es un día

Ver este jsFiddle actualizado http://jsfiddle.net/6aqtj/1/

+0

Gracias, esperaba que podría ser una manera de hazlo dentro de la plantilla sin alterar la matriz en el controlador. Sin embargo, no parece que esto sea posible en este momento. – DaveJ

+2

Creé un filtro que se puede reutilizar basado en esta respuesta: http://jsfiddle.net/interlock/qhewP/2/ – jsapara

4

Estoy de acuerdo con Renan acerca de la matriz de matrices y quede atrapado en un intento de hacer esto más como un calendario. Suponiendo que desea celdas de la tabla en blanco y desea que el mes comience el día correcto de la semana (0-6). Echar un vistazo a esta función:

function generateWeeks(startDay, numDays){ 
    var weeks = []; 
    var numWeeks = (numDays + startDay)/7; 
    for(var i=0; i<numWeeks; i++){ 
    weeks[i] = []; 
    for(var j=0; j<7; j++){ 
     if(i==0 && j<startDay){ 
     weeks[i].push(''); 
     }else{ 
     var day = (j-startDay+1)+(i*7); 
     weeks[i].push(day<=numDays ? day : ''); 
     } 
    } 
    } 
    return weeks; 
} 

Para el mes en curso, me gustaría llamar generateWeeks (5,30). Septiembre tiene 30 días y comenzó el sábado (y su semana calendario es de lunes a domingo).

<tr ng-repeat="week in weeks"> 
    <td ng-repeat="day in week">{{day}} 
</tr> 
9

Si desea dejar sus datos alcance la forma en que es (como una matriz), se podría escribir una directiva, y encapsular toda la generación de HTML no, por lo tanto:

<div ng-controller="MyCtrl"> 
    <calendar></calendar> 
</div> 

myApp.directive('calendar', function() { 
// Requires that scope contains a 'monthDays' array. 
// Adds 'weeks' to scope. 
return { 
    restrict: 'E', 
    replace: true, 
    template: '<table cellspacing="0" cellpadding="0">' 
    + ... 
    + '<th scope="col" title="Sunday">Sun</th></tr>' 
    + '<tr ng-repeat="week in weeks">' 
    + '<td ng-repeat="day in week">{{day}}</td>' 
    + '</tr></tbody></table>', 
    link: function(scope) { 
     scope.weeks = []; 
     for (var i = 0; i < scope.monthDays.length; i++) { 
      if (i % 7 == 0) { 
       scope.weeks.push([]); 
      } 
      scope.weeks[scope.weeks.length-1].push(scope.monthDays[i]); 

Fiddle: http://jsfiddle.net/mrajcok/dGpsr/

5

Puede hacerlo fácilmente con sus datos actuales. Acabo de agregar un filtro simple: http://jsfiddle.net/3zhbB/6/

No es realmente la mejor solución, ya que es bastante ineficiente. Tendrá que crear una nueva matriz y hacer muchos cortes. Pero todavía está genial :-D

+2

Me gustó mucho esta solución. Es una lástima que la publicación SO sea tan breve cuando el jsfiddle al que apunta es tan elegante. Con underscore.js, sin embargo, es aún mejor: 'myApp.filter ('array', function() {return _.range;});' –

1

Acabo de tener este problema yo mismo. Sin embargo, en lugar de tablas html, voy a usar una lista desordenada en una sola colección de "días" y usar css para que parezca una tabla. Por lo tanto, si cada elemento tiene un ancho del 14%, se ajustará automáticamente a 7.

Este fue el origen de mi enfoque: Creating three-column table with CSS only? (No table element)

0

Se puede usar un condicional como $index % 7 == 0 para escribir el </tr><tr>

acabo de crear una tabla sencilla como esto:

<style type="text/css"> 
    .selectable.year { 
     display:inline-block; 
     width:25%; 
     border-right-width:0px; 
     text-align: center; 
    } 
    .selectable.year.first { 
     margin-left:0; 
    } 
    .selectable.year.lastcol, .selectable.year:last-child { 
     border-right-width:1px; 
    } 
</style> 
<div class="calendar"> 
    <div class="selectable year" 
     ng-class="{ 'firstcol' : $index % 4 == 0 , 'lastcol' : $index % 4 == 3 }" 
     ng-repeat="year in search.yearList" 
     <span class="caption">{{ year }}</span> 
    </div> 
</div> 

como puedes ver, se envuelve ... no es una mesa, realmente.

Cuestiones relacionadas