AngularJS: 光标移动到模型转换时的最后位置
AngularJS: Cursor is moving to last position when model is transformed
我正在使用 zipcode 指令,它接受 9 位美国邮政编码并对其进行格式化。
app.directive('formatZipCode', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModelCtrl) {
function fromUser(text) {
if (text) {
var transformedInput = text.replace(/[^0-9]/g, '');
if (transformedInput.length > 9) {
transformedInput = transformedInput.slice(0, 9);
}
if (transformedInput.length > 5) {
transformedInput = transformedInput.slice(0, 5) + "-" + transformedInput.slice(5);
}
if (transformedInput !== text) {
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
}
return transformedInput;
}
return undefined;
}
ngModelCtrl.$parsers.push(fromUser);
}
};
});
当我从邮政编码中删除任何数字时,光标位置会移回上一个位置。
When I delete third number cursor moves to last number
如何保持光标位置?
您最好的选择是使用 ng-model-options
来更改输入更新的时间(从而运行您的格式化程序)。
在这种情况下,您将牺牲实时重新格式化以支持表单可用性。
要么使用
<input type="text" ng-model="zipcode" ng-model-options="{ updateOn: 'blur' }" format-zip-code />
在用户离开字段时更新,或者
<input type="text" ng-model="zipcode" ng-model-options="{ debounce: 1000 }" format-zip-code />
1s
后更新。此选项在更新后仍会显示光标移动到输入的末尾,但不会立即移动。
我已经通过使用插入符位置解决了这个问题。记住插入符号的位置,并在格式化输入后再次分配插入符号的位置。
app.directive('formatZipCode', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModelCtrl) {
function fromUser(text) {
if (text) {
var transformedInput = text.replace(/[^0-9]/g, '');
if (transformedInput.length > 9) {
transformedInput = transformedInput.slice(0, 9);
}
var caretPosition = element[0].selectionStart || undefined;
if (transformedInput.length > 5) {
var realposition = caretPosition == 6 ? caretPosition + 1 : caretPosition;
transformedInput = transformedInput.slice(0, 5) + "-" + transformedInput.slice(5);
}
if (transformedInput !== text) {
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
if (typeof caretPosition === 'number') {
element[0].selectionStart = element[0].selectionEnd = realposition || caretPosition;
}
else {
element[0].selectionStart = element[0].selectionEnd = 0;
}
}
return transformedInput;
}
return undefined;
}
ngModelCtrl.$parsers.push(fromUser);
}
};
});
我正在使用 zipcode 指令,它接受 9 位美国邮政编码并对其进行格式化。
app.directive('formatZipCode', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModelCtrl) {
function fromUser(text) {
if (text) {
var transformedInput = text.replace(/[^0-9]/g, '');
if (transformedInput.length > 9) {
transformedInput = transformedInput.slice(0, 9);
}
if (transformedInput.length > 5) {
transformedInput = transformedInput.slice(0, 5) + "-" + transformedInput.slice(5);
}
if (transformedInput !== text) {
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
}
return transformedInput;
}
return undefined;
}
ngModelCtrl.$parsers.push(fromUser);
}
};
});
当我从邮政编码中删除任何数字时,光标位置会移回上一个位置。 When I delete third number cursor moves to last number
如何保持光标位置?
您最好的选择是使用 ng-model-options
来更改输入更新的时间(从而运行您的格式化程序)。
在这种情况下,您将牺牲实时重新格式化以支持表单可用性。
要么使用
<input type="text" ng-model="zipcode" ng-model-options="{ updateOn: 'blur' }" format-zip-code />
在用户离开字段时更新,或者
<input type="text" ng-model="zipcode" ng-model-options="{ debounce: 1000 }" format-zip-code />
1s
后更新。此选项在更新后仍会显示光标移动到输入的末尾,但不会立即移动。
我已经通过使用插入符位置解决了这个问题。记住插入符号的位置,并在格式化输入后再次分配插入符号的位置。
app.directive('formatZipCode', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModelCtrl) {
function fromUser(text) {
if (text) {
var transformedInput = text.replace(/[^0-9]/g, '');
if (transformedInput.length > 9) {
transformedInput = transformedInput.slice(0, 9);
}
var caretPosition = element[0].selectionStart || undefined;
if (transformedInput.length > 5) {
var realposition = caretPosition == 6 ? caretPosition + 1 : caretPosition;
transformedInput = transformedInput.slice(0, 5) + "-" + transformedInput.slice(5);
}
if (transformedInput !== text) {
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
if (typeof caretPosition === 'number') {
element[0].selectionStart = element[0].selectionEnd = realposition || caretPosition;
}
else {
element[0].selectionStart = element[0].selectionEnd = 0;
}
}
return transformedInput;
}
return undefined;
}
ngModelCtrl.$parsers.push(fromUser);
}
};
});