Bootgrid格式化器中点击事件失效,如何结合Knockout使用点击事件?
解决jQuery Bootgrid + Knockout点击事件绑定失效问题
我来帮你拆解下问题原因,再给出两种可行的解决方案:
为什么你的点击绑定没生效?
你的代码里有两个核心问题:
绑定目标选择器错误
你写了document.getElementById("MyDiv")[0],但getElementById返回的是单个DOM元素(不是数组),加[0]会导致获取到undefined,直接让Knockout的绑定操作失败了。动态生成元素未被Knockout处理
Bootgrid的格式化器是直接把HTML字符串插入DOM的,哪怕你之后执行applyBindings,Knockout也不会自动解析这些动态插入的data-bind属性——因为Knockout只会处理绑定操作执行时已经存在于DOM中的元素。
方案1:手动为动态元素绑定Knockout事件
我们可以利用Bootgrid的row事件(行被插入DOM时触发),手动给操作按钮绑定Knockout的点击事件:
function VM() { var self = this; self.GetDetails = function(_e, actionType) { alert("Hi"); } } // 先创建ViewModel实例 var vm = new VM(); // 初始化bootgrid,利用row事件处理动态元素绑定 var userGrid = $("#UserList").bootgrid({ caseSensitive: false, formatters: { "Actions": function (column, curr) { // 这里不用加data-bind,我们之后手动绑定 return "<a href='#' class='on-default edit-row'>Hello</a>"; } }, // 当行被添加到DOM时触发 row: function(row) { // 找到当前行的操作按钮 var actionBtn = row.find(".edit-row"); // 手动给按钮绑定Knockout点击事件 ko.applyBindingsToNode(actionBtn[0], { click: vm.GetDetails }, vm); } }).bootgrid("append", data); // 正确应用绑定到容器(去掉多余的[0]) ko.applyBindings(vm, document.getElementById("MyDiv"));
方案2:让Knockout主导视图渲染(更推荐)
如果你的表格数据本身是Knockout可观察数组,建议让Knockout负责渲染表格内容,Bootgrid只做样式和交互增强。这种方式从根源上避免动态DOM的绑定问题:
HTML部分
<div id="MyDiv"> <table id="UserList" class="table table-striped"> <thead> <tr> <!-- 这里放你的其他表头列 --> <th data-column-id="Actions">操作</th> </tr> </thead> <tbody data-bind="foreach: userList"> <tr> <!-- 其他列用Knockout绑定数据,比如:<td data-bind="text: username"></td> --> <td> <a href="#" data-bind="click: $parent.GetDetails" class="on-default edit-row">Hello</a> </td> </tr> </tbody> </table> </div>
JavaScript部分
function VM() { var self = this; // 用可观察数组存储表格数据,方便后续更新自动刷新视图 self.userList = ko.observableArray(data); self.GetDetails = function(currentRow) { // currentRow就是当前点击行的数据对象,能直接访问行数据 alert("你点击了行:" + JSON.stringify(currentRow)); } } var vm = new VM(); // 先完成Knockout绑定,渲染表格内容 ko.applyBindings(vm, document.getElementById("MyDiv")); // 最后初始化bootgrid,只做样式和交互增强 $("#UserList").bootgrid({ caseSensitive: false });
小提示
- 如果你用方案1,记得不要重复绑定同一个元素,可以用
ko.dataFor(element)检查元素是否已经绑定过ViewModel。 - 确保Bootgrid和Knockout的版本没有兼容性冲突。
内容的提问来源于stack exchange,提问作者Dhineshkumar T
相关产品推荐
相关产品推荐

