ASP.NET MVC视图通过开关状态计算采购总价值列的实现问题
现有代码问题
- 缺失总价值列的DOM结构:表头和每行末尾都没有增加Total Value对应的列元素,没有容器用来展示计算结果
- 无有效取值逻辑:你尝试通过
getElementById获取Qty和Amount数值,但DOM中没有给对应元素设置ID,且循环生成的多行列如果用ID会出现重复冲突,无法正确获取当前行、当前供应商的对应数值 - 函数作用域错误:
calculate函数被定义在IsApproved函数内部,属于局部函数,change事件回调中无法调用,计算逻辑自然不会执行 - 数据类型未处理:从DOM中获取的Qty和报价金额都是字符串类型,未转换为数字就直接相乘,可能出现NaN的计算错误
- 未处理开关取消选中的场景:只做了选中时的计算逻辑,没有考虑用户取消选中时总价值的回退/重新计算逻辑
完整修改方案
第一步:修改HTML结构
首先增加总价值的表头列,每行末尾增加总价值展示列,同时给对应元素加上自定义data属性存数值,方便JS取值:
<div class="card-body"> <!-- 表头部分 --> <div class="row"> <div class="col-md-3 col-sm-3"> <strong>Item Description</strong> </div> <div class="col-md-1 col-sm-1"> <strong>Quantity</strong> </div> @foreach (var item in Model.ToList().First().PurchasingDetailsSup) { <div class="col-md-2 col-sm-2"> <strong> @Suppliers.Find(x => x.Value == item.Supp_Id.ToString()).Text</strong> </div> } <!-- 新增总价值表头 --> <div class="col-md-2 col-sm-2"> <strong>Total Value</strong> </div> </div> @foreach (Asp_PASMVC.Models.PurchasingDetails item in Model) { <div class="row"> <div class="col-md-3"> @item.Item_Description </div> <!-- 给数量列加data属性存数量值 --> <div class="col-md-1 qty-col" data-qty="@item.Qty"> @item.Qty </div> @for (int i = 0; i < item.PurchasingDetailsSup.Count; i++) { <!-- 给供应商列加data属性存单价 --> <div class="col-md-2 sup-col" data-unit-amount="@item.PurchasingDetailsSup[i].Unit_Amount"> @item.PurchasingDetailsSup[i].Unit_Amount <!-- 修正checked初始状态赋值 --> <input type="checkbox" @(item.PurchasingDetailsSup[i].IsApproved ? "checked" : "") class="bootstrap-switch bwitch" data-style="ios" data-id="@item.PurchasingDetailsSup[i].Id" data-onstyle="success" data-offstyle="danger" /> </div> } <!-- 新增总价值展示列 --> <div class="col-md-2 total-value"> 0 </div> </div> } </div>
第二步:修改JS逻辑
调整函数作用域,新增当前行取值逻辑,处理数字类型转换,完成计算:
$(".bootstrap-switch").change(function () { var isChecked = this.checked; var id = $(this).data('id'); // 先拿到当前行元素 var $currentRow = $(this).closest('.row'); // *如果业务要求同一行只能选中一个供应商,可放开下方注释实现单选逻辑 // if(isChecked){ // $currentRow.find('.bootstrap-switch').not(this).prop('checked', false).trigger('change'); // } // 获取当前行的数量 var qty = parseFloat($currentRow.find('.qty-col').data('qty')); // 获取当前开关对应的供应商单价 var unitAmount = parseFloat($(this).closest('.sup-col').data('unit-amount')); // 获取当前行的总价值容器 var $totalVal = $currentRow.find('.total-value'); // 调用接口更新状态 IsApproved(id, isChecked); // 计算总价值 calculate(qty, unitAmount, isChecked, $totalVal); }); // 移到外部,全局可调用 function calculate(qty, unitAmount, isChecked, $totalContainer) { // 允许多个供应商同时选中时累加金额,不需要累加可直接赋值为qty * unitAmount var currentTotal = parseFloat($totalContainer.text()) || 0; if (isChecked) { currentTotal += qty * unitAmount; } else { // 取消选中就减去对应金额 currentTotal -= qty * unitAmount; } // 保留2位小数展示 $totalContainer.text(currentTotal.toFixed(2)); } function IsApproved(id, chkValue) { $.ajax({ url: '../UpdateApproveStatus', type: 'POST', dataType: 'json', cache: false, async: false, data: { Id: id, IsChecked: chkValue }, success: function (data) { if (data.Success != true) { console.log('Error In IsApprove'); } } }); }
内容的提问来源于stack exchange,提问作者user1983377
相关产品推荐
相关产品推荐

