Input cursor position jumps to end with ng-change()

谁都会走 提交于 2019-12-04 04:13:13

问题


I have an instance where I'm replacing the value of ngModel through ngChange. The cursor jumps to the end of the input field after each change (assuming because I'm assigning the result to the same $scope variable.)
I'd like to know how I can prevent this behavior?

  $scope.compute1 = 0;
  $scope.compute2 = 10;

  $scope.math = function() {
    $scope.compute1 = parseInt($scope.compute1);
    $scope.compute2 = parseInt($scope.compute2);

    $scope.compute1 = parseInt($scope.compute1);
  };

fiddle

Example of problem: if a user types in 1000. It's fine. But then if they want to go back and change the number to 156000 by just adding the 5 and 6, the 6 would actually be appended to the end: 15006.


回答1:


The cursor goes to the end because we modify data by using parseInt.

I suggest you to store the caret position before and then when you're done doing things, set it back.

This example might help you: Link




回答2:


Two suggestions:

1 Why not just use number input.

<div ng-app='myApp'>
    <div ng-controller="myCtrl">
    <input id="compute1" ng-model="compute.c1" ng-change="math()" type="number"/>
    <input id="compute2" ng-model="compute.c2" ng-change="math()" type="number"/>
  </div>
</div>

2 Two-Way databinding should always be used with the "dot" notation:

$scope.compute = {c1: 0, c2: 10};

$scope.math = function() {
  $scope.compute.c1 = parseInt($scope.compute.c1);
  $scope.compute.c2 = parseInt($scope.compute.c2);
};

and update your html accordingly to have ng-model="compute.c1" etc.




回答3:


Depending on what math() does, you could make the computation happen on blur instead of change. This way the conversion will only happen when the user tabs (or clicks) out of the input.

See Angularjs: input[text] ngChange fires while the value is changing for an example of this.




回答4:


I just wrote this directive which basically allows you to format the text and keep cursor position it's not flawless but works pretty well. Just make sure to return the value in the format function instead of actually changing the value and use it the same as you would the regular ng-change:

.directive('ngChangeFormat', function() {
        return {
            restrict: 'A',
            require: '?ngModel',
            link: function(scope, element, attr, controller) {
                controller.$viewChangeListeners.push(function() {
                    var el = element[0];
                    var start = el.selectionStart;
                    var end = el.selectionEnd;
                    var originalValue = controller.$viewValue;
                    var formattedValue = scope.$eval(attr.ngChangeFormat);
                    controller.$setViewValue(formattedValue);
                    controller.$render();
                    if(start === originalValue.length)
                        el.setSelectionRange(formattedValue.length, formattedValue.length);
                    else
                        el.setSelectionRange(start, end);
                });
            }
        };
    })



回答5:


Very quick and simple fix to delay the ng-model-options. I had the same issue this worked for me: on your input ->

ng-model-options="{debounce: 750}"


来源:https://stackoverflow.com/questions/20203216/input-cursor-position-jumps-to-end-with-ng-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!