【问题标题】:AngularJS display input value in a different format while keeping the same format in modelAngularJS 以不同的格式显示输入值,同时在模型中保持相同的格式
【发布时间】:2017-09-20 09:57:38
【问题描述】:

我得到一个整数,表示以分钟为单位的持续时间,但如果大于特定值,我想将其显示为小时或天,但我仍想以分钟为单位保留 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 小时,但我担心控制台中的错误消息。

【问题讨论】:

  • 用户如何知道输入中的值是小时还是天?我认为它应该是指令而不是过滤
  • 持续时间值总是以分钟为单位存储和发送,但应用程序应该能够以不同的格式显示它们,同时在逻辑中仍然以分钟为单位保持值,所以当它再次发送时,几分钟后。用户将通过数字输入旁边的标签知道它是否以分钟/小时/天显示。好的,所以应该使用指令而不是过滤器?

标签: javascript angularjs


【解决方案1】:

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

Formatters and Parsers

基本上,对于我的解决方案,我创建了新指令来实现 hoursdays 的逻辑,格式化程序执行逻辑,解析器反转逻辑,否则 ng-model 将丢失原始值。检查我下面的sn-p!

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>

【讨论】:

  • 哇,惊人的回复!非常感谢纳伦。只有一个问题:是否可以将其组合成一个指令?我不想创建多个输入并动态显示/隐藏它们,所以只显示一个。
  • @Laureant 当然为什么不呢!这是做到这一点的方法! (更新了我的答案)我已经为输入类型(time-parser="hours")设置了一种方式绑定,如果你愿意,你可以改变它!
猜你喜欢
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-27
  • 2021-05-10
  • 1970-01-01
相关资源
最近更新 更多