2011-08-29 29 views
5

Estoy tratando de agregar una nueva fila al final de la tabla cuando el usuario comienza a escribir en la última fila. El modelo de vista se parece a éste:Agregar automáticamente una nueva fila a la tabla al editar la última

function tableRow(number, ownerViewModel) { 
    this.number = ko.observable(number); 
    this.remove = function() { ownerViewModel.tableRows.destroy(this); } 

    ko.dependentObservable(function() { 
     var curval = this.number(); 
     var rows = ownerViewModel.tableRows(); 
     if (rows.length > 0) { 
      if (curval != '' && this == rows[rows.length - 1]) { 
       ownerViewModel.addNewRow(); 
      } 
     } 
    }, this); 
} 

function tableRowsViewModel() { 
    var that = this; 
    this.tableRows = ko.observableArray([]); 
    this.addNewRow = function() { 
     this.tableRows.push(new tableRow('', that)); 
    } 
    this.addNewRow(); 
} 

$(document).ready(function() { 
    ko.applyBindings(new tableRowsViewModel()); 
}); 

Y aquí es html:

<table> 
    <thead> 
     <tr> 
      <th> 
       Number 
      </th> 
      <th> 
      </th> 
     </tr> 
    </thead> 
    <tbody data-bind="template:{name:'tableRow', foreach: tableRows}"> 
    </tbody> 
    <tfoot> 
     <tr> 
      <td colspan="4"> 
       <button type="button" data-bind="click: addNewRow"> 
        add row 
       </button> 
      </td> 
     </tr> 
    </tfoot> 
</table> 
<script id="tableRow" type="text/html"> 
    <tr> 
     <td> 
      <input type="text" style="width:40px;" data-bind="value: number, valueUpdate: 'keyup'" /> 
     </td> 
     <td> 
      <button type="button" data-bind="click: function(){ $data.remove(); }"> 
       delete 
      </button> 
     </td> 
    </tr> 
</script> 

También he insertado alert() en función TableRow ko.dependentObservable:

ko.dependentObservable(function() { 
    alert('test'); 
    var curval = this.number();... 

Parece esta función se dispara 5 veces cuando la matriz tableRows contiene 2 elementos, 6 veces cuando hay 3 elementos en la matriz y así sucesivamente.

¿Estoy haciendo esto bien?

Respuesta

7

El dependObservable que está agregando a cada objeto de fila se activa cada vez que se agrega una fila, ya que dependen de tableRows. Entonces, cada uno está trabajando para determinar si son la última fila. Si es la última fila, se agrega una nueva fila.

Una alternativa es usar un solo dependienteObservable que representa el valor de la última fila. Luego, puede suscribirse a los cambios en ese dependienteObservable, verificar si tiene un valor y agregar una fila cuando sea necesario. Se vería algo como: http://jsfiddle.net/rniemeyer/F5F8S/

Además, aquí es una muestra que tenía de los foros KO que muestra la adición de una fila y también la eliminación de la última fila si los dos últimos son vacía en caso de que ayuda: http://jsfiddle.net/rniemeyer/MzGDr/

+1

Gracias por el enlace jsfiddle. ¿Alguna idea de por qué http://jsfiddle.net/rniemeyer/F5F8S/ funciona con knockout-2.0.0 pero no con el último knockout-2.1.0? – MLH

+3

Hubo un cambio en 2.1 que no permite que un observable calculado se vuelva a evaluar incluyendo suscripciones a sí mismo. La solución más fácil es hacer la fila agregar en un setTimeout para que no esté en el mismo contexto de ejecución como: http://jsfiddle.net/rniemeyer/F5F8S/17/ –

+0

¡Excelente! Muchas gracias por la respuesta. – MLH

Cuestiones relacionadas