Knockout.js嵌套foreach绑定表格时数据行挤在同一行异常求解
问题原因
- HTML绑定逻辑错误
你把foreach: coaDetails绑定到了<tr>标签上,这会让Knockout为每个明细项生成同一条行内的<td>,所有明细数据就会挤在同一行展示,这就是你看到多行数据并排的直接原因。 - JS数据映射错误
你使用jQuery的$.each()处理明细数组,$.each()执行后返回的是原数组本身,不会返回你新创建的AddCoaDetails实例数组,最终coaDetails里存储的还是原始接口数据,不是你封装的观测模型。 - 可选优化项:
AddCoaDetails中部分字段非观测类型,如果后续需要更新字段值会出现异常,建议统一封装为observable。
修正方案
1. 修正HTML代码
<form> <!-- detail form here --> <button type="button" data-bind="click: $root.getReport">GET DATA</button> </form> <!-- 外层遍历每个COA,每个COA对应一个独立表格结构 --> <!-- ko foreach: coas --> <table style="width: 100%"> <thead> <tr><th colspan="5"><span data-bind="text: coaname">COA NAME</span></th></tr> <tr> <th style="width: 20%">date</th> <th style="width: 20%">account</th> <th style="width: 20%">debet</th> <th style="width: 20%">credit</th> <th style="width: 20%">saldo</th> </tr> </thead> <!-- 明细遍历放在tbody上,每个明细生成独立一行 --> <tbody data-bind="foreach: coaDetails"> <tr> <td data-bind="text: date">### date ###</td> <td data-bind="text: coa">### account ###</td> <td data-bind="text: debet">### debet ###</td> <td data-bind="text: credit">### credit ###</td> <td data-bind="text: saldo">### saldo ###</td> </tr> </tbody> </table> <!-- /ko -->
2. 修正JS代码
function AddCoaDetails(date,coa,debet,credit,saldo){ var self= this; self.date = ko.observable(date); self.coa = ko.observable(coa); // 统一为observable类型,避免后续更新异常 self.debet = ko.observable(debet == 0 ? '' : addPeriod(debet,",")); self.credit = ko.observable(credit == 0 ? '' : addPeriod(credit,",")); self.saldo = ko.observable(saldo == 0 ? '' : addPeriod(saldo,",")); } function AddCoaModel(coaname,detail){ var self = this; self.coaname = ko.observable(coaname); self.coaDetails = ko.observableArray(detail) } function LedgerModel(){ var self = this; self.coas = ko.observableArray([]); self.getReport = function(){ $.ajax({ // 保留你原有ajax配置项 success: function(listcoa) { var mappedCoas = listcoa.map(function (i) { // 把$.each替换为Array.map,返回封装后的实例数组 var coadetail = i.detail.map(function(item) { return new AddCoaDetails(item.date, item.coa, item.debet, item.credit, item.saldo); }); return new AddCoaModel(i.namecoa, coadetail); }); self.coas(mappedCoas); } }) } } ko.applyBindings(new LedgerModel());
内容的提问来源于stack exchange,提问作者Dewi Griselda
相关产品推荐
相关产品推荐

