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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:36:03