为google.visualization.datatable创建先进的KnockOut绑定处理程序 [英] Creating advanced KnockOut binding handler for google.visualization.datatable
问题描述
感谢此教程我设法为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());
//获取选项:
var options = allBindings.get(tableOptions)|| {};
//默认选项:
options.width = options.width || 为200px;
options.height = options.height || 为200px;
options.showRowNumber = options.showRowNumber ||假;
//获取事件:
var onSelected = allBindings.get(select)||假;
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事件做出反应。
我在处理程序中使用 //获取事件
部分尝试了此操作,但这不起作用。
在我的HTML中添加 select:$ root.selectedRow(),
在我的函数 selectedRow()
我把 console.log(In selectedRow)
。当我加载页面时,我发现每行都会调用 selectedRow
,但是当我点击一行时,就不会调用它。
该行的背景更改为橙色,因此Google将添加 selectedTableRow
类。
包装/绑定到选择事件?
主要的问题是,如果我没有弄错, 您的 $(元素).on(select,onSelect)
不是你正在使用的库附加事件监听器的方式。在文档中,您可以看到实际需要使用: google.visualization.events.addListener(table,'select',selectHandler);
另外,事件侦听器在 init
方法中。 update
在您的数据更改时会被调用,因此它可能会添加多个事件侦听器。
这是您的一个工作示例code:
google.charts.load('current',{'packages':['table']}); google.charts。 setOnLoadCallback(函数(){ko.bindingHandlers.dataTable = {INIT:功能(元件,valueAccessor,allBindings,视图模型,的BindingContext){风险表=新google.visualization.Table(元件); ko.utils.domData.set(元件,dataTable,table); //获取事件: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)); //发送点击行的薪水}); }},update:function(element,valueAccessor,allBindings,viewModel,bindingContext){var value = ko.unwrap(valueAccessor()); //获取选项:var options = allBindings.get(tableOptions)|| {}; //默认选项:options.width = options.width || 为200px; options.height = options.height || 为200px; options.showRowNumber = options.showRowNumber ||假; 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'},真实],['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 type =tex t / javascriptsrc =https://www.gstatic.com/charts/loader.js>< / script>< div data-bind =dataTable:getData(),tableOptions:{width:' 100%,高度: '200像素', 'allowHtml':真, 'cssClassNames':{ 'selectedTableRow': '橙背景'}},选择:ONSELECT>< / DIV>
Thanks to this tutorial I managed to create a KnockOut binding handler for Google's DataTable. This is my binding handler, so far:
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);
}
};
This is my HTML part:
<div data-bind="dataTable: $root.getData(), tableOptions: {width: '100%',height: '200px', 'allowHtml': true, 'cssClassNames': {'selectedTableRow': 'orange-background'} }"></div>
So far I get a table with fixed headers which works just fine.
Now I want to extent to binding handler to react on the 'select row' event.
I tried this using the // Get events
section in my handler but this is not working.
In my HTML I add select: $root.selectedRow(),
In my function selectedRow()
I put a console.log("In selectedRow")
. When I load the page I see selectedRow
is called for every row, but when I click on a row it is not called.
The row its background is changed to orange, so Google is adding the selectedTableRow
class.
How to wrap/bind to the select event?
The main thing that's going wrong is, if I'm not mistaken, the way you're trying to attach your event listener.
Your $(element).on("select", onSelect)
is not how the library you're using attaches event listeners. In the documentation you can see that you actually need to use: google.visualization.events.addListener(table, 'select', selectHandler);
Additionally, it's better to attach the event listener in the init
method. update
is called whenever your data changes, so it might add multiple event listeners.
Here's a working example of your 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>
这篇关于为google.visualization.datatable创建先进的KnockOut绑定处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!