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

如何在AngularJS+WebAPI中利用ng-change保持表格内文本框焦点?

嘿,我知道这个问题有多烦——改数量的时候输入框突然失焦,每次都得重新点进去,太影响体验了!让我帮你搞定它~

首先得搞清楚为什么会失焦:你在ng-change触发的txtqty函数里,把后端返回的整个response.data直接赋值给了$scope.gridproducts。这会让AngularJS的ng-repeat认为整个列表都变了,于是把原来的所有行都销毁,重新渲染一遍。原来的输入框都被删掉重建了,焦点自然就没了。


最优解决方案:只更新变化的Item,不替换整个数组

这个方法最优雅,能从根源上解决问题,因为我们不让ng-repeat重新渲染所有行,只更新需要改变的属性。

修改你的AngularJS代码:

$scope.txtqty = function (item) { 
  var id = item.Id; 
  $http.put("/api/Products/txtqty/" + id, item).then(function (response) { 
    // 从返回的数据里找到对应的更新后的item
    const updatedProduct = response.data.find(prod => prod.Id === id);
    if (updatedProduct) {
      // 把更新后的属性合并到原来的item上,而不是替换整个数组
      Object.assign(item, updatedProduct);
      
      // 同步所有item的TotalBill(后端会统一更新这个全局值)
      $scope.gridproducts.forEach(prod => {
        prod.TotalBill = updatedProduct.TotalBill;
      });
    }
  }) 
}

同时,把HTML里input的value="{{item.ProductQty}}"删掉——ng-model已经完成了数据绑定,加value完全是多余的,还可能导致冲突:

<input class="form-control qty" type="text" style="width:50px" ng-change="txtqty(item)" ng-model="item.ProductQty">

备选方案:强制恢复焦点(如果必须替换数组)

要是因为某些原因你不得不替换整个gridproducts数组,那可以在DOM更新后手动把焦点切回去。不过这个方法不如第一个优雅,只能作为兜底:

先给input加上动态ID:

<input class="form-control qty" type="text" style="width:50px" ng-change="txtqty(item, $index)" ng-model="item.ProductQty" id="qty-input-{{$index}}">

然后修改AngularJS函数,用$timeout等待DOM更新后再设置焦点(记得要在控制器里注入$timeout服务):

// 控制器注入$timeout依赖
$scope.txtqty = function (item, index) { 
  var id = item.Id; 
  $http.put("/api/Products/txtqty/" + id, item).then(function (response) { 
    $scope.gridproducts = response.data;
    // 用$timeout等待Angular完成DOM渲染
    $timeout(function() {
      document.getElementById(`qty-input-${index}`).focus();
    });
  }) 
}

优先用第一种方法哦,它不仅能解决焦点问题,还能提升页面性能——毕竟不用重新渲染整个列表啦!

内容的提问来源于stack exchange,提问作者user9179360

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:23:38