AngularJS $ formatters和$ parsers使用input [number]箭头错误地修改模型

时间:2016-07-28 15:51:19

标签: javascript angularjs html5

我正在尝试让数字输入字段工作,以允许用户以他们希望的任何单位(Hz,kHz,MHz或GHz)指定频率。无论用户对显示和输入的偏好如何,模型都应始终以Hz为单位存储实际频率。

我希望的行为如下:

  • 始终以Hz为单位存储值
  • 始终以kHz
  • 显示值
  • 更新模型时将用户的编辑内容从kHz转换为Hz
  • 正确地遵守最小/最大值(2kHz - 18 MHz)
  • 步进输入字段,步长为'1',以1000 Hz步长更新模型。

我实际遇到的事情:

  • 如果我在输入中输入“2”,模型会正确更新为2000 Hz并且验证器都可以使用
  • 如果我然后单击向上微调器箭头(或按向上箭头键),则值将在输入字段中捕捉到2000,并且模型设置为2000000 Hz。

如何确保微调器箭头和箭头键正常工作?

我有一个Plunker here,以kHz为单位模拟此行为。

我的HTML代码是:

<body ng-app="docsSimpleDirective">
  <form name="myForm" ng-controller="Controller">
  <label>Frequency (kHz):
    <input magnitude-converter type="number" name="input" ng-model="example.value"
           min="2000" max="18000000" step="1" required>
 </label>
  <div role="alert">
    <span class="error" ng-show="myForm.input.$error.required">
      Required!</span>
    <span class="error" ng-show="myForm.input.$error.number">
      Not valid number!</span>
  </div>
  <tt>value (Hz) = {{example.value}}</tt><br/>
  <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
  <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
 </form>
</body>

我的JS代码是:

(function(angular) {
  'use strict';
angular.module('docsSimpleDirective', [])
  .controller('Controller', ['$scope', function($scope) {
    $scope.customer = {
      name: 'Naomi',
      address: '1600 Amphitheatre'
    };
  }])
  .directive('magnitudeConverter', function() {
    return {
      require: 'ngModel',
      link: function (scope, element, attrs, ngModel) {
        var parser = function(value) {
          var parsedValue = value * 1000;
          return parsedValue;
        };
        var formatter = function(value) {
          var formattedValue = value / 1000;
          return formattedValue;
        };
        ngModel.$parsers.push(parser);
        ngModel.$formatters.push(formatter);
      }
    };
  });
})(window.angular);

1 个答案:

答案 0 :(得分:1)

这是因为您在min="2000"元素中指定了input,这是现代浏览器的功能,如果指定的值错误,它们会将值设置为最小值。 / p>

要解决此问题,您可以将min="2000"更改为min="2"(因为您要转换它)或删除min&amp; max约束并添加一个自定义验证器(在Angular 1.3.0中引入),如下所示:

ngModel.$validators.myFooValidation = function(modelValue, viewValue) {
    return modelValue >= 2000 && modelValue <= 18000000;
}

然后显示错误:

<div ng-show="myForm.input.$error.myFooValidation">
   Value should be between 2 to 18000
</div>