AngularJS以不同的格式显示输入值,同时在模型

时间:2017-09-20 09:57:38

标签: javascript angularjs

我得到一个整数,表示以分钟为单位的持续时间,但是如果大于特定值,我想将其显示为小时或天,但我仍然希望将ng-model值保持在几分钟内,因此,如果用户对值进行了任何更改,并且我的应用程序将其读回,则应该在几分钟内完成。

例如: 如果我读了480分钟',显示应该是8(小时)。 如果我读了1440分钟'它应该是1(天)。 如果用户将其更改为0.5(天),那么ng-model中的值应为720。

我想将数字部分保留在输入中,而测量单位(分钟/小时/天)保留在输入右侧的标签中。

我创造了一个'持续时间'过滤器看起来像这样:

myApp.filter('duration', function() {
  //Returns duration from minutes in hours
    return function(minutes) {
      var hours = Math.floor(minutes / 60);
      return hours;
    }
});

然而,当我将它添加到以下元素

...list iteration through fields, where textField is the current iteration object
    <input type="number" class="text-input" ng-model="textField.CustomFieldValue | duration">

它在控制台中显示错误消息:

[ngModel:nonassign] Expression 'textField.CustomFieldValue | duration' is non-assignable. Element: <input type="number" class="text-input ng-pristine ng-untouched ng-valid" ng-model="textField.CustomFieldValue | duration">

我知道我的过滤器不正确(但是),但我只是用它进行了一些测试。

我对AngularJS并不熟悉,所以我可能会以错误的方式使用过滤器。

过滤器工作正常,因此值为480,我显示8小时,但我担心控制台中的错误消息。

1 个答案:

答案 0 :(得分:1)

我不认为在filter附加ng-model是个好主意!它主要会给您max-digest错误。这是我的解决方案,实施ng-model formatters and parsers,这是一篇很棒的文章,让你开始这个!

Formatters and Parsers

基本上对于我的解决方案,我创建了新的指令,它将实现hoursdays的逻辑,格式化器执行逻辑,解析器反转逻辑,否则ng-model将松散原始价值。检查我的下面片段!

var app = angular.module('myApp', []);

app.controller('MyController', function MyController($scope) {
  $scope.textField = 480;
});

app.directive('timeParser', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    scope: {
      timeParser: "@"
    },
    link: function(scope, element, attr, ngModel) {
      ngModel.$formatters.push(function(minutes) {
        if (scope.timeParser === "hours") {
          return Math.floor(minutes / 60);
        } else if (scope.timeParser === "days") {
          return Math.floor(minutes / (60 * 24));
        } else {
          return minutes;
        }
      });

      ngModel.$parsers.push(function(minutes) {
        if (scope.timeParser === "hours") {
          return Math.floor(minutes * 60);
        } else if (scope.timeParser === "days") {
          return Math.floor(minutes * (60 * 24));
        } else {
          return minutes;
        }
      });

    }
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller='MyController' ng-app="myApp">
  Minutes
  <input type="number" class="text-input" ng-model="textField">
  <br> Hours
  <input type="number" class="text-input" ng-model="textField" time-parser="hours">
  <br> Days
  <input type="number" class="text-input" ng-model="textField" time-parser="days">
</div>