问题
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