Angular 9实现点击首表项复制数据至次表并递增数量
嘿,我看到你在Angular 9开发中遇到了表格商品添加的问题——点击第一个表格的商品项要同步到第二个表格,重复商品还要自动递增数量对吧?你的现有代码只是简单克隆行并追加,没处理重复商品判断和数量、总价更新的核心逻辑,这就是达不到预期效果的原因。下面我给你整理了完整的解决方案,用jQuery就能搞定:
解决方案:表格商品添加/数量递增实现
第一步:优化HTML结构
先把第二个表格里的空行去掉,留空tbody方便动态插入内容,同时移除原代码里无效的id="moveMeIntoMain"(因为*ngFor会生成多个相同id,不符合HTML规范):
<table class="table table-hover" id="firstTable"> <thead class="table-primary"> <tr> <td>Code</td> <td>Item</td> <td>Unit</td> <td>Price</td> </tr> </thead> <tbody> <tr *ngFor="let data of itemList;" style="cursor:pointer"> <td>{{data.itemCode}}</td> <td>{{data.itemName}}</td> <td><span>{{data.unitId}}</span>{{data.name}}</td> <td>{{data.retailRate}}</td> </tr> </tbody> </table> <table class="table table-hover" id="secondTable"> <thead class=""> <tr class="table-primary"> <td>#</td> <td>Item</td> <td>Price</td> <td>Quantity</td> <td>Action</td> </tr> </thead> <tbody> <!-- 动态内容将在这里生成 --> </tbody> </table>
第二步:重写jQuery核心逻辑
我们用一个数组来跟踪已添加的商品数据(数据驱动DOM,避免直接操作DOM导致的状态混乱),同时处理重复判断、数量更新,还额外加了移除商品的功能:
$(document).ready(function () { // 存储已添加商品的核心数据:商品名、单价、数量、总价 let cartItems = []; const $secondTableBody = $("#secondTable tbody"); // 绑定第一个表格行的点击事件 $("#firstTable tbody tr").on("click", function () { // 提取当前点击行的商品信息 const $currentRow = $(this); const itemName = $currentRow.find("td:eq(1)").text().trim(); const singlePrice = parseFloat($currentRow.find("td:eq(3)").text().trim()); // 检查商品是否已在购物车中 const existingItemIndex = cartItems.findIndex(item => item.itemName === itemName); if (existingItemIndex !== -1) { // 商品已存在:递增数量,更新总价 cartItems[existingItemIndex].quantity += 1; cartItems[existingItemIndex].totalPrice = cartItems[existingItemIndex].quantity * singlePrice; // 更新对应DOM行的内容 updateExistingCartRow(existingItemIndex); } else { // 商品不存在:添加新条目到数组和表格 const newCartItem = { itemName: itemName, singlePrice: singlePrice, quantity: 1, totalPrice: singlePrice * 1 }; cartItems.push(newCartItem); addNewCartRow(newCartItem); } }); // 辅助函数:向第二个表格添加新行 function addNewCartRow(item) { const rowNumber = cartItems.length; const $newRow = $(` <tr> <td>${rowNumber}</td> <td>${item.itemName}</td> <td>${item.totalPrice}</td> <td>${item.quantity}</td> <td><button class="btn btn-sm btn-danger remove-item">移除</button></td> </tr> `); // 绑定移除按钮事件 $newRow.find(".remove-item").click(function() { const targetItemName = $(this).closest("tr").find("td:eq(1)").text().trim(); // 从数组中删除对应商品 cartItems = cartItems.filter(cartItem => cartItem.itemName !== targetItemName); // 删除DOM行 $(this).closest("tr").remove(); // 更新剩余行的序号 refreshCartRowNumbers(); }); $secondTableBody.append($newRow); } // 辅助函数:更新已存在的购物车行 function updateExistingCartRow(index) { const $cartRows = $secondTableBody.find("tr"); const targetRow = $cartRows.eq(index); targetRow.find("td:eq(2)").text(cartItems[index].totalPrice); targetRow.find("td:eq(3)").text(cartItems[index].quantity); } // 辅助函数:移除商品后刷新行号 function refreshCartRowNumbers() { $secondTableBody.find("tr").each(function(index) { $(this).find("td:eq(0)").text(index + 1); }); } });
关键逻辑说明
- 数据优先:用
cartItems数组存储商品状态,所有DOM操作都基于这个数组,避免直接操作DOM导致的状态不一致。 - 重复判断:通过
findIndex检查商品名称是否已存在,存在则更新数量和总价,不存在则添加新条目。 - 可维护性:把添加行、更新行、刷新行号的逻辑拆成独立函数,代码更清晰易改。
- 用户体验优化:额外添加了移除按钮,方便用户删除不需要的商品(你可以根据需求保留或删除这部分)。
小提示
虽然jQuery能解决问题,但因为你用的是Angular 9,更推荐用Angular响应式数据绑定实现(比如用*ngFor渲染第二个表格,点击事件用Angular的(click)绑定),这样更符合Angular的开发规范。不过如果你坚持用jQuery,上面的代码完全可以满足需求,记得把jQuery代码放到Angular的ngAfterViewInit生命周期钩子中,确保DOM渲染完成后再绑定事件。
内容的提问来源于stack exchange,提问作者Dream OC
相关产品推荐
相关产品推荐

