2013-01-03 10 views
5

Ich versuche, mit dem savesort-Widget salesorter zu verwenden. Die Tabelle wird von knokout aufgefüllt.jQuery-Tablesorter mit Knockout - Zeilen hinzufügen

Wenn die Tabelle zum ersten Mal ausgefüllt wird, erhalte ich die richtige Anzahl an Zeilen und merkt sich die Sortierung. Ich befülle dann die Tabelle mit Daten, indem ich Ajax und Bindung an das Knockout-Array verwende. Die Daten werden dann verdoppelt, aber Knockout (korrekt), verfolgt nur die Hälfte der Daten.

Bisher habe ich es nach unten verfolgt, wenn ich die gespeicherte Sortierung in dieser Methode anwenden:

self.tablesorter = function() { 
         $('table.tablesorterTranslation').trigger("update"); 
         setTimeout(function() { 
          var sl = $.tablesorter.storage($('table.tablesorterTranslation'), 'tablesorter-savesort'); 
          var sortList = (sl && sl.hasOwnProperty('sortList') && $.isArray(sl.sortList)) ? sl.sortList : ''; 
          if (sortList && sortList.length > 0) { 
           // update sort change 
           $('table.tablesorterTranslation').trigger("sorton", [sortList]); 
          } 
         }, 1000); 
         return false; 
        }; 

Diese Methode wird von Vorprägungen genannt Bindung Postaction.

Bevor die Methode aufgerufen wird, habe ich eine Tabelle für jedes Element im Knockout-Array, nach dem Postaction, ich habe zwei, eine durch Knockout verfolgt, und eine, die von tablesorter hinzugefügt wird.

Ist dies auf die Cache-Werte von tablesorter zurückzuführen, und gibt es eine Möglichkeit, sie zu bereinigen?

Die html:

<table class="tablesorterTranslation" data-bind="visible: contents().length > 0"> 
       <colgroup> 
        <col class="referencenumber"/> 
        <col class="title"/> 
       </colgroup> 
       <thead> 
        <tr> 
         <th class="referencenumber">Ref number</th> 
         <th class="title">Title</th> 
        </tr> 
       </thead> 
       <tbody data-bind="foreach: contents, postAction: tablesorter(), visible: contents().length > 0"> 
        <tr> 
         <td class="referencenumber"> 
          <span data-bind="text: contentReferenceNumber"></span> 
         </td> 
         <td class="title"> 
          <a data-bind="attr: {href: previewUrl, title: previewTitle}, click: previewpopup" class="preview_translation"><%: AdminResources.Menu_Preview %></a> 
         </td> 
       </tr> 
      </tbody> 
     </table> 

Ajax, die die Tabelle füllt ihn wieder:

self.setContentList = function() { 
         if ($('#LanguageIdNameValuePairs option').length > 0) { 
          self.contents.removeAll(); 
          self.loading(true); 
          $.ajax('<%= Url.Action("GetContentList", "TranslateContentMenu") %>', 
           { 
            dataType: 'json', 
            data: { 
             languageId: $('#LanguageIdNameValuePairs').val(), 
             page: self.page 
            }, 
            success: function (allData) { 
             var mappedContent = $.map(allData, function (item) { return new ContentViewModel(item); }); 
             self.loading(false); 
             self.contents(mappedContent); 
            } 
           }); 
         } else { 
          self.contents(new Array()); 
         } 
        }; 

Die contentviewmodel:

(function (ko) { 
    PODIUM.translation.ContentViewModel = function(data) { 
     this.contentReferenceId = ko.observable(data.contentReferenceId); 
     this.contentName = data.contentName; 
     this.previewUrl = ko.observable(data.previewUrl); 
     this.previewTitle = ko.observable(data.previewTitle); 
     this.publishTitle = ko.observable(data.publishTitle); 
     this.contentReferenceNumber = ko.observable(data.contentReferenceNumber); 
    }; 
}(ko)); 

und die letzte, um die Tabelle Bestücken und Definieren tablesort mit savesort (Savesort ist das Problem, denke ich).

 $('#OptionsMenu').change(function() { 
      viewModel.setContentList(); 
     }); 
     $('table.tablesorterTranslation').tablesorter({ 
      widgets: ["saveSort"], 
      widgetOptions: {} 
     }); 

Ich habe eine Auswahlliste, mit einigen Werten, wenn sich dies ändert, i neue Werte vom Server erhalten und die Tabelle neu zu besiedeln. Hier erinnert es sich an alte Werte, aber ich möchte die Tabelle "säubern" und neu beginnen.

+0

Haben Sie eine Live-Demo, die Sie teilen könnten? – Mottie

+0

Leider nein, es ist kein öffentliches System, ich werde sehen, ob ich etwas mehr Code zur Verfügung stellen kann. – ruffen

Antwort

2

Ich fand selbst eine Antwort, aber nicht die, die ich wollte.

Grundsätzlich, da ich knockout verwende, soll ich keine Änderungen an der Ansicht selbst vornehmen, sondern das Viewmodel ändern. Also habe ich mir die Sortierung der Arrays angeschaut und den Rest der Magie knockout gemacht.

Ich begann mit dem Entfernen aller Spuren von tablesorter (mit Ausnahme der CSS-Klasse in der Tabelle, da ich dies bereits im Stylesheet verwendet habe).

Dann habe ich diese Methode:

  self.sortContents = function (element, sortProperty) { 
       var elem = $(element); 
       var direction = (elem.hasClass('headerSortDown')) ? 'headerSortUp' : 'headerSortDown'; 
       var selector = $.trim($(element).attr('class').replace('header', '').replace('headerSortUp', '').replace('headerSortDown', '')); 
       if (direction == 'headerSortUp') { 
        self.filterStorage.updateSortFilter(selector, sortProperty); 
        self.contents.sort(function(left, right) { 
         return left[sortProperty] == right[sortProperty] ? 0 : (left[sortProperty] > right[sortProperty] ? -1 : 1); 
        }); 
        elem.removeClass('headerSortDown'); 
        elem.addClass('headerSortUp'); 
       } else { 
        self.filterStorage.updateSortFilter(selector, sortProperty); 
        self.contents.sort(function (left, right) { 
         return left[sortProperty] == right[sortProperty] ? 0 : (left[sortProperty] < right[sortProperty] ? -1 : 1); 
        }); 
        elem.removeClass('headerSortUp'); 
        elem.addClass('headerSortDown'); 
       } 
      }; 

Hinweis im die gleichen CSS-Klassen wie tablesort Plugin, das ist, weil tablesorter bereits an anderen Orten in der Anwendung verwendet wird, und die CSS ist schon da für diejenigen, Klassen.

i änderte den Tabellenkopf dazu:

<th class="title header" data-bind="click: function(data, event){ return sortContents($(event.target), 'contentName')}"><%: AdminResources.ContentOverview_Title %></th> 

Dann, da ich in diesem Chaos stand auf und versucht, die Art Zustand zu speichern, ich etwas dafür herauszufinden musste. Also habe ich eine neue Klasse mit Methoden, update und get erstellt. Damit wird gespeichert, mit welcher Kopfzeile und mit welcher Richtung sortiert wird.

function getSortFilter() { 
    var cookie = $.cookie(tableSortedByCookie); 
    return JSON.parse(cookie); 
} 
function updateSortFilter(selector, property) { 
    $.cookie(tableSortedByCookie, null); 
    $.cookie(tableSortedByCookie, JSON.stringify({ selector: selector, property: property }), { path: '/' }); 
} 

Sie können die Verwendung von update in sortcontents-Methode sehen. (Diese Methode befindet sich im Ansichtsmodell für die Seite, die die Tabelle enthält).

Ich habe dann dieses auf den Boden der Ajax-Erfolg Methode:

var tableSortCookie = self.filterStorage.getSortFilter(); 
if (tableSortCookie != null && tableSortCookie.selector != null) { 
    var header = $('.tablesorterTranslation th.' + tableSortCookie.selector); 
    self.sortContents(header, tableSortCookie.property); 
} 

Und dann konnte ich die Daten sortieren Knockout statt verwenden, sowie den Zustand zu speichern und laden den Zustand zurück, wenn Daten ändern und die Seite aktualisieren.