2011-08-29 24 views
5

Próbuję dodać nowy wiersz na końcu tabeli, gdy użytkownik zacznie pisać w ostatnim wierszu. ViewModel wygląda to jedno:Automatyczne dodawanie nowego wiersza do tabeli podczas edycji ostatniego

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()); 
}); 

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

Ja również włożona alert() w funkcji TableRow ko.dependentObservable:

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

Wydaje się, ta funkcja jest uruchamiana 5 razy, gdy tablica tableRows zawiera 2 elementy, 6 razy, gdy są 3 elementy w tablicy i tak dalej.

Czy robię to dobrze?

Odpowiedz

7

Obiekt zależnyObożliwość dodawania do każdego obiektu wiersza jest uruchamiany za każdym razem, gdy dodawany jest wiersz, ponieważ zależą one od tableRows. Tak więc każdy z nich wykonuje pewne czynności, aby ustalić, czy są ostatnim rzędem. Jeśli jest to ostatni wiersz, dodaje się nowy wiersz.

Alternatywą jest użycie pojedynczego obiektu dependObservable, który reprezentuje wartość ostatniego wiersza. Następnie możesz zasubskrybować zmiany do dependObservable, sprawdzić, czy ma wartość i dodać wiersz, gdy jest to konieczne. Byłoby to wyglądać mniej więcej tak: http://jsfiddle.net/rniemeyer/F5F8S/

Również tutaj jest przykład, że miałem z forów KO, które znajdują się dodając wiersz, a także usuwania ostatni wiersz czy dwa ostatnie są puste w przypadku pomaga: http://jsfiddle.net/rniemeyer/MzGDr/

+1

Dzięki za link jsfiddle. Każdy pomysł, dlaczego http://jsfiddle.net/rniemeyer/F5F8S/ działa z nokautem-2.0.0, ale nie z najnowszym nokautem-2.1.0? – MLH

+3

W wersji 2.1 nastąpiła zmiana, która nie pozwala, aby obliczone obserwowalne powodowało ponownej oceny, w tym subskrypcje samego siebie. Najłatwiejszym rozwiązaniem jest dodanie wiersza do metody setTimeout, aby nie było w tym samym kontekście wykonania, jak na przykład: http://jsfiddle.net/rniemeyer/F5F8S/17/ –

+0

Doskonały! Dziękuję bardzo za odpowiedź. – MLH

Powiązane problemy