为google.visualization.datatable创建高级KnockOut绑定处理程序

时间:2016-05-01 13:18:14

标签: javascript jquery knockout.js google-visualization

感谢这个tutorial 我设法为Google的DataTable创建了一个KnockOut绑定处理程序。 到目前为止,这是我的绑定处理程序:

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

这是我的HTML部分:

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

到目前为止,我得到了一个带有固定标题的表格,工作正常。 现在我想扩展绑定处理程序以对'select row'事件做出反应。 我在我的处理程序中使用// Get events部分尝试了这个但是这不起作用。

在我的HTML中,我添加了select: $root.selectedRow(), 在我的函数selectedRow()中,我添加了console.log("In selectedRow")。当我加载页面时,我看到每行调用selectedRow,但是当我点击一行时,它不会被调用。

该行的背景更改为橙色,因此Google正在添加selectedTableRow类。

如何包装/绑定到select事件?

1 个答案:

答案 0 :(得分:2)

出现问题的主要原因是,如果我没有弄错的话,就是你尝试附加事件监听器的方式。

您的$(element).on("select", onSelect)不是您使用的库如何附加事件侦听器。在documentation中,您可以看到实际需要使用:google.visualization.events.addListener(table, 'select', selectHandler);

此外,最好在init方法中附加事件监听器。只要数据发生变化,就会调用update,因此它可能会添加多个事件侦听器。

以下是您的代码的工作示例:

&#13;
&#13;
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;

    }
  })
});
&#13;
<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>
&#13;
&#13;
&#13;