我有几个表单字段需要以USD($ n.nn)显示,并且已成功使用自定义货币指令。但是我已经添加了NgModelOptions来控制去抖:
{updateOn:'默认模糊',去抖动:{'默认':100,'模糊':0}}“
当字段更新然后快速退出时,此工作正常除外,在这种情况下显示先前值。然后输入然后离开该字段将导致显示正确的值。
有关如何将指令或货币过滤器与NgModelOptions结合使用的所有想法,以便显示的值反映退出时的模型值?
这是当前的指令:
.directive('ngCurrency', function ($filter, $locale) {
return {
require: 'ngModel',
scope: {
min: '=min',
max: '=max',
ngRequired: '=ngRequired'
},
link: function (scope, element, attrs, ngModel) {
function decimalRex(dChar) {
return RegExp("\\d|\\" + dChar, 'g');
}
function clearRex(dChar) {
return RegExp("((\\" + dChar + ")|([0-9]{1,}\\" + dChar + "?))&?[0-9]{0,2}", 'g');
}
function decimalSepRex(dChar) {
return RegExp("\\" + dChar, "g");
}
function clearValue(value) {
value = String(value);
var dSeparator = $locale.NUMBER_FORMATS.DECIMAL_SEP;
var clear = null;
if (value.match(decimalSepRex(dSeparator))) {
clear = value.match(decimalRex(dSeparator))
.join("").match(clearRex(dSeparator));
clear = clear ? clear[0].replace(dSeparator, ".") : null;
}
else if (value.match(decimalSepRex("."))) {
clear = value.match(decimalRex("."))
.join("").match(clearRex("."));
clear = clear ? clear[0] : null;
}
else {
clear = value.match(/\d/g);
clear = clear ? clear.join("") : null;
}
return clear;
}
ngModel.$parsers.push(function (viewValue) {
cVal = clearValue(viewValue);
return parseFloat(cVal);
});
element.on("blur", function () {
element.val($filter('currency')(ngModel.$modelValue));
scope.$apply();
});
ngModel.$formatters.unshift(function (value) {
return $filter('currency')(value);
});
scope.$watch(function () {
return ngModel.$modelValue;
}, function (newValue, oldValue) {
runValidations(newValue);
});
function runValidations(cVal) {
if (!scope.ngRequired && isNaN(cVal)) {
return;
}
if (scope.min) {
var min = parseFloat(scope.min);
ngModel.$setValidity('min', cVal >= min);
}
if (scope.max) {
var max = parseFloat(scope.max);
ngModel.$setValidity('max', cVal <= max);
}
}
}
}
})
答案 0 :(得分:0)
element.on("blur", function () {
element.val($filter('currency')(ngModel.$modelValue));
scope.$apply();
});
我假设正在发生的是你正在更改一个字段并离开它,这会导致摘要周期被触发 - 这会使你的事件回调中的范围。$ apply()尝试在它已被执行时执行。解决方法通常是将整个调用包装在$ timeout中。
element.on("blur", function () {
$timeout(function() {
element.val($filter('currency')(ngModel.$modelValue));
scope.$apply();
});
});
我很确定当发生这种情况时,控制台会显示某种错误信息 - 供将来参考。
您是否有任何理由不直接在模型上使用过滤器,例如:{{my.model |货币}}而不是添加一个事件?似乎是不好的做法。