2011-10-06 6 views
13

he encontrado una pregunta similar/contestar aquí: How to render a table with some fixed and some dynamic columnsKnockout.js - columnas dinámico, pero limite a un máximo de 5 para cada fila

Pero no resuelve por completo mi problema. Estoy tratando de descubrir cómo puedo limitar el número de columnas dinámicas a 5 por fila y si hay más de 5 elementos en el modelo de vista, haga una nueva fila y repita para todos los grupos de 5 en la matriz.

Por ejemplo:

var vm = { 
    item: { name: 'test1' }, 
    item: { name: 'test2' }, 
    item: { name: 'test3' }, 
    item: { name: 'test4' }, 
    item: { name: 'test5' }, 
    item: { name: 'test6' } 
}; 

Dale ese modelo, ¿cómo puedo obtener esta tabla?

<table> 
    <tr> 
     <td>test1</td> 
     <td>test2</td> 
     <td>test3</td> 
     <td>test4</td> 
     <td>test5</td> 
    </tr> 
    <tr> 
     <td>test6</td> 
    <tr> 
</table> 

Respuesta

24

Para manejar una situación como esta, probablemente inserte la lógica en su modelo de vista, para que su vista pueda seguir siendo simple. Entonces, la idea sería usar un dependienteDebservable para representar sus "filas". Entonces, su punto de vista puede simplemente atravesar las filas y luego llegar a través de las celdas de su fila.

Aquí hay una muestra que hace que ese número de columnas sea observable, de modo que pueda actualizarse dinámicamente. http://jsfiddle.net/rniemeyer/9TN9W/

var viewModel = { 
    items: ko.observableArray(), 
    columnLength: ko.observable(5) 
}; 

//sample data 
for (var i = 0; i < 100; i++) { 
    viewModel.items.push({ name: 'test' + i }); 
} 

//return an array of rows. Each row is an array of items 
viewModel.rows = ko.dependentObservable(function() { 
    var result = [], 
     colLength = parseInt(this.columnLength(), 10), 
     row; 


    //loop through items and push each item to a row array that gets pushed to the final result 
    for (var i = 0, j = this.items().length; i < j; i++) { 
     if (i % colLength === 0) { 
      if (row) { 
       result.push(row);  
      } 
      row = []; 
     } 
     row.push(this.items()[i]); 
    } 

    //push the final row 
    if (row) { 
     result.push(row); 
    } 

    return result; 
}, viewModel); 
+0

Ah, eso es perfecto y puedo vivir con esos cambios de viewModel. Probablemente mantengo mi viewModel emitido desde el servidor igual mientras lo manipulo en JavaScript para resolver este problema tal como lo ha demostrado. ¡Muchas gracias! :) – ChrisS

+2

Para cualquier persona interesada en un ejemplo de solución, aquí es con lo que finalmente terminé: http://jsfiddle.net/cmschick/hyHQW/ Al final solo creo la tabla dinámicamente. Están sucediendo muchas cosas en este ejemplo, ordenando, vinculando, actualizando, columnas dinámicas que no envolverán el texto, etc. pero puede ser útil para alguien. – ChrisS

+0

+1 Impresionante, justo lo que estaba buscando :) –

1

Lo más cerca que he sido capaz de llegar a una solución es la siguiente:

<table> 
    <tbody> 
      <tr data-bind="template: { name: 'rowTmpl', foreach: items}"> 

      </tr> 
    </tbody> 
</table> 
<script id="rowTmpl" type="text/html"> 

     <td data-bind="text: name"></td> 

     <!-- ko if: (vm.items.indexOf($data) + 1) % 5 == 0 --> 
     <td>new row html here</td> 
     <!-- /ko --> 

</script> 


vm = { 

      items: ko.observableArray([ 
       { name: 'test1' }, 
       { name: 'test2' }, 
       { name: 'test3' }, 
       { name: 'test4' }, 
       { name: 'test5' }, 
       { name: 'test6' } 
      ]) 
     } 

     ko.applyBindings(vm); 

.. que da salida a esto:

| test1 | test2 | test3 | test4 | test5 | nueva fila html aquí | test6 |

Esto inserta un nuevo elemento en cada 5to elemento. Sin embargo, si sustituyo <td>new row html here</td> con </tr><tr>, el motor de la plantilla arroja un error. Tal vez, algún otro SO-er puede basarse en esto y mostrar cómo la salida no es estrictamente correcta html.

De todos modos, espero que esto ayude un poco.

+0

Gracias Marcar por la ayuda. Eso es más o menos lo que pude obtener también. Parece como si de alguna manera necesitara llamar al alcance vinculante $ parent y cambiar la plantilla para empujar otro tr ... ¿Cómo diablos hacer eso es el problema. Hola Steve Sanderson, ¿cómo puede hacerse esto o CAN? Gracias. – ChrisS

Cuestiones relacionadas