NgModelOptions + Currency Filter =字段不显示模型

时间:2015-08-01 23:33:57

标签: angularjs filter currency directive

我有几个表单字段需要以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);
            }
          }
        }
      }
    })

1 个答案:

答案 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 |货币}}而不是添加一个事件?似乎是不好的做法。