You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bootgrid格式化器中点击事件失效,如何结合Knockout使用点击事件?

解决jQuery Bootgrid + Knockout点击事件绑定失效问题

我来帮你拆解下问题原因,再给出两种可行的解决方案:


为什么你的点击绑定没生效?

你的代码里有两个核心问题:

  1. 绑定目标选择器错误
    你写了document.getElementById("MyDiv")[0],但getElementById返回的是单个DOM元素(不是数组),加[0]会导致获取到undefined,直接让Knockout的绑定操作失败了。

  2. 动态生成元素未被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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:20:19