我在下面有一个<input type="text>
字段
myApp.directive('onlyDecimal', function ()
{
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl)
{
if(!ngModelCtrl)
{
return;
}
ngModelCtrl.$parsers.push(function(val)
{
if (angular.isUndefined(val))
{
var val = "";
}
var clean = "";
if(val !== null)
{
clean = val.replace(/[^0-9\.]/g, "");
}
var start = element[0].selectionStart;
var end = element[0].selectionEnd + clean.length - val.length;
var negativeCheck = clean.split("-");
var decimalCheck = clean.split(".");
if(!angular.isUndefined(negativeCheck[1]))
{
negativeCheck[1] = negativeCheck[1].slice(0, negativeCheck[1].length);
clean = negativeCheck[0] + '-' + negativeCheck[1];
if(negativeCheck[0].length > 0)
{
clean = negativeCheck[0];
}
}
if(!angular.isUndefined(decimalCheck[1]))
{
decimalCheck[1] = decimalCheck[1].slice(0,2);
clean = decimalCheck[0] + "." + decimalCheck[1];
}
if (val !== clean)
{
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
element[0].setSelectionRange(start, end);
return clean;
});
element.bind("keypress", function(event)
{
if(event.keyCode === 32)
{
event.preventDefault();
}
});
var decimalCount = 2;
var decimalPoint = ".";
ngModelCtrl.$render = function()
{
if (ngModelCtrl.$modelValue != null && ngModelCtrl.$modelValue >= 0)
{
if (typeof decimalCount === "number")
{
element.val(ngModelCtrl.$modelValue.toFixed(decimalCount).toString().replace(".", ","));
}
else
{
element.val(ngModelCtrl.$modelValue.toString().replace(".", ","));
}
}
}
element.on("change", function(e)
{
var floatValue = parseFloat(element.val().replace(",", "."));
if (!isNaN(floatValue) && typeof decimalCount === "number")
{
if (decimalCount === 0)
{
element.val(parseInt(floatValue));
}
else
{
var strValue = floatValue.toFixed(decimalCount);
element.val(strValue.replace(".", decimalPoint));
}
}
});
}
};
});
该指令的目的是仅允许字段中的数字和1位小数。
假设我的值为50.00
然后我将插入符号设置为位置0之前的值,并输入键b
的无效值。在设置选择范围之前设置了console.log,我得到了这些值:
START: 0 END: 1
START: 0 END: 0
它运行两次,似乎仍然将插入符号移动到下一个位置。
答案 0 :(得分:0)
您的代码中至少存在两个导致问题行为的问题:
在ngModelCtrl.$render
中,您正在检查decimalCount
的类型,以确定$modelValue
是数字还是字符串。一旦开始输入,ngModelCtrl.$modelValue
就会变成一个字符串,但是你的逻辑仍会尝试在其上调用.toFixed()
,导致渲染异常,并阻止setSelectionRange
被调用解析器。
您的格式化程序中未使用正在交换小数点逗号的逻辑。带有逗号的值将进入,创建clean
的正则表达式将删除它,因为它期望小数。解决此问题后,您还必须修复最后val
和clean
之间的比较,以便将小数点交换回clean
中的逗号。
总的来说,我建议如下:
if (typeof decimalCount === "number")
交换为if (typeof ngModelCtrl.$modelValue === "number")
clean
clean
中的逗号,然后再将其与原始val
进行比较。