2016-05-01 3 views
0

Dank dieser tutorial konnte ich einen KnockOut-Bindungs-Handler für Googles DataTable erstellen. Dies ist meine Bindung Handler, so weit:Erstellen von erweiterten KnockOut-Bindungs-Handler für google.visualization.datatable

ko.bindingHandlers.dataTable = { 
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { 
     var table = new google.visualization.Table(element); 
     ko.utils.domData.set(element, "dataTable", table); 
    }, 

    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { 
     var value = ko.unwrap(valueAccessor()); 

     // Get options: 
     var options = allBindings.get("tableOptions") || {}; 
     // Default options: 
     options.width = options.width || "200px"; 
     options.height = options.height || "200px"; 
     options.showRowNumber = options.showRowNumber || false; 

     // Get events: 
     var onSelected = allBindings.get("select") || false; 
     if (onSelected) { 
      $(element).on("select", function(event, ui) { 
       valueAccessor()(ui.value); 
      }); 
     } 

     var table = ko.utils.domData.get(element, "dataTable"); 
     table.draw(value, options); 
    } 
}; 

Das ist mein HTML-Teil:

<div data-bind="dataTable: $root.getData(), tableOptions: {width: '100%',height: '200px', 'allowHtml': true, 'cssClassNames': {'selectedTableRow': 'orange-background'} }"></div> 

Bisher bekomme ich eine Tabelle mit festen Header, die ganz gut funktioniert. Nun möchte ich den Binding-Handler erweitern, um auf das 'select row' -Ereignis zu reagieren. Ich versuchte dies mit der // Get events Abschnitt in meinem Handler, aber das funktioniert nicht.

In meinem HTML ich hinzufügen select: $root.selectedRow(), In meiner Funktion selectedRow() ich eine console.log("In selectedRow") setzen. Wenn ich die Seite lade, sehe ich selectedRow wird für jede Zeile aufgerufen, aber wenn ich auf eine Zeile klicke, wird sie nicht aufgerufen.

Die Zeile, deren Hintergrund in Orange geändert wurde, fügt Google die selectedTableRow Klasse hinzu.

Wie wird das ausgewählte Ereignis umgebrochen/gebunden?

+0

Haben Sie den Ereignis-Listener versucht, indem mit 'google.visualization.events.addListener (Tabelle, 'wählen', select); '? – user3297291

+0

Meinst du "draußen" KnockOut? Auf meiner Seite habe ich mehrere Tabellen. Meine Tabellen sind eng. Wenn ich auf eine Zeile klicke, möchte ich die vollständigen Zeilendaten in einem Div unterhalb der Tabelle anzeigen. Ich muss also wissen, in welcher Tabelle ich bin und welche Zeile ich ausgewählt habe. Um das div zu füllen, benutze ich ein Observable, ich muss nur wissen, wie man dieses Observable füllt. –

+0

Ich meinte in Ihrem Binding-Handler, anstatt der '$ (Element) .on (" Select ", ...'. – user3297291

Antwort

2

Die Hauptsache, die falsch läuft, ist, wenn ich mich nicht irre, die Art, wie Sie Ihren Ereignis-Listener anhängen möchten.

Ihre $(element).on("select", onSelect) ist nicht, wie die Bibliothek, die Sie verwenden, Ereignislistener anhängt. In der documentation können Sie sehen, dass Sie tatsächlich verwenden müssen: google.visualization.events.addListener(table, 'select', selectHandler);

Darüber hinaus ist es besser, den Ereignislistener in der init-Methode anzuhängen. update wird aufgerufen, wenn sich Ihre Daten ändern, sodass möglicherweise mehrere Ereignis-Listener hinzugefügt werden.

Hier ist ein funktionierendes Beispiel für Code:

google.charts.load('current', { 
 
    'packages': ['table'] 
 
}); 
 

 
google.charts.setOnLoadCallback(function() { 
 

 
    ko.bindingHandlers.dataTable = { 
 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
     var table = new google.visualization.Table(element); 
 
     ko.utils.domData.set(element, "dataTable", table); 
 

 
     // Get events: 
 
     var onSelected = allBindings.get("select") || false; 
 
     if (onSelected) { 
 
     google.visualization.events.addListener(table, 'select', function() { 
 
      // TODO: null/undefined/multiple selection checks 
 
      var data = valueAccessor(); 
 
      var row = table.getSelection()[0].row; 
 
      onSelected(data.getValue(row, 1)); // Sends salary of clicked row 
 
     }); 
 
     } 
 

 
    }, 
 

 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
     var value = ko.unwrap(valueAccessor()); 
 

 
     // Get options: 
 
     var options = allBindings.get("tableOptions") || {}; 
 
     // Default options: 
 
     options.width = options.width || "200px"; 
 
     options.height = options.height || "200px"; 
 
     options.showRowNumber = options.showRowNumber || false; 
 

 

 
     var table = ko.utils.domData.get(element, "dataTable"); 
 
     table.draw(value, options); 
 
    } 
 
    }; 
 

 
    ko.applyBindings({ 
 
    onSelect: function(value) { 
 
     alert(value); 
 
    }, 
 
    getData: function() { 
 
     var data = new google.visualization.DataTable(); 
 
     data.addColumn('string', 'Name'); 
 
     data.addColumn('number', 'Salary'); 
 
     data.addColumn('boolean', 'Full Time Employee'); 
 
     data.addRows([ 
 
     ['Mike', { 
 
      v: 10000, 
 
      f: '$10,000' 
 
      }, 
 
      true 
 
     ], 
 
     ['Jim', { 
 
      v: 8000, 
 
      f: '$8,000' 
 
      }, 
 
      false 
 
     ], 
 
     ['Alice', { 
 
      v: 12500, 
 
      f: '$12,500' 
 
      }, 
 
      true 
 
     ], 
 
     ['Bob', { 
 
      v: 7000, 
 
      f: '$7,000' 
 
      }, 
 
      true 
 
     ] 
 
     ]); 
 
     return data; 
 

 
    } 
 
    }) 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> 
 
<div data-bind="dataTable: getData(), tableOptions: {width: '100%',height: '200px', 'allowHtml': true, 'cssClassNames': {'selectedTableRow': 'orange-background'} }, select: onSelect"></div>

+0

Danke für diese sehr erklärende Antwort. Ich habe noch eine Frage: Wie bekomme ich den Wert des ausgewählten Zeile? Ich nahm an, dass ich verwenden konnte 'onSelect: function (row) { alert (" Auswahl "+ Zeile); }' aber Zeile ist leer. getSelection() benötigt eine Tabelle und ich habe mehrere Tabellen. –

+0

Sie könnten Umhüllen Sie Ihre 'onSelected' in einer anonymen Methode. Bei dieser Methode bezieht sich' table' auf die "aktuelle" Tabelle und Sie können sie an die Auswahlmethode übergeben, zB: 'google.visualization.events.addListener (table, 'select ', function() {onSelected (table.getSelection());}); ' – user3297291

+0

Es tut mir leid, weiter zu fragen, aber es scheint, dass Sie eine Menge darüber wissen;)' table.getSelection() 'gibt ein Array mit zurück die ausgewählten Zeilen- und Spaltenindizes no t der tatsächliche Wert. Ich habe versucht, 'table' in meine onSelected:' google.visualization.events.addListener (table, 'select', function() {onSelected (table);}); 'und benutze' var item = table.getSelection() [0]; console.log (table.getValue (item.row, 3)); 'Aber' getValue' ist für das Tabellenobjekt nicht verfügbar. Ich denke, ich sollte es auf die tatsächlichen Daten nennen, aber ich habe diese Variable nicht als global. –

Verwandte Themen