如何在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
相关产品推荐
相关产品推荐

