【问题标题】:How to round in Javascript/Angular JS -- but remove insignificant digits如何在 Javascript/Angular JS 中四舍五入——但删除无关紧要的数字
【发布时间】:2015-01-08 22:34:33
【问题描述】:

我的 Javascript 控制器中有以下语句:

$scope.myList = [0, 1, 0.5, 0.6666666];

我的 AngularJS 模板包含以下行:

<div ng-repeat="i in myList">{{i}}</div>

这会产生以下 HTML 输出:

<div>0</div>
<div>1</div>
<div>0.5</div>
<div>0.6666666</div>

我希望将数字四舍五入到小数点后 2 位。 但是,我希望在输出中只看到有效数字。我不想看到尾随零。我该怎么做?使用 {{i | number:2}} 并不能消除尾随零。

【问题讨论】:

  • 四舍五入到两位,然后再次转换为真数
  • &lt;div ng-repeat="i in myList"&gt;{{(i | number:2)*1}}&lt;/div&gt;
  • [0, 1, 0.5, 0.6666666].map(function(el){ return el.toFixed(2); }).map(Number)

标签: javascript html angularjs angularjs-filter


【解决方案1】:

您可以将其乘以 1 以将其转换为真值。

<div ng-repeat="i in myList">{{(i | number:2)*1}}</div>

如 cmets 所述,由于角度数字过滤器的语言环境格式化,上述解决方案将中断。如果您需要区域设置格式和舍入,您可以创建一个扩展过滤器,它在下面使用 number filter$locale 服务。

.filter('numberEx', ['numberFilter', '$locale',
  function(number, $locale) {

    var formats = $locale.NUMBER_FORMATS;
    return function(input, fractionSize) {
      //Get formatted value
      var formattedValue = number(input, fractionSize);

      //get the decimalSepPosition
      var decimalIdx = formattedValue.indexOf(formats.DECIMAL_SEP);

      //If no decimal just return
      if (decimalIdx == -1) return formattedValue;


      var whole = formattedValue.substring(0, decimalIdx);
      var decimal = (Number(formattedValue.substring(decimalIdx)) || "").toString();

      return whole +  decimal.substring(1);
    };
  }
]);

并将其用作:

  <div ng-repeat="i in myList">{{i | numberEx:2}}</div>

演示

angular.module('app', []).controller('ctrl', function($scope) {

  $scope.myList = [0, 10000.56, 0.5, 0.6666666, -1000.23123, 1, 1002, 2.5, 30.5, 22];

}).filter('numberEx', ['numberFilter', '$locale',
  function(number, $locale) {

    var formats = $locale.NUMBER_FORMATS;
    return function(input, fractionSize) {
      //Get formatted value
      var formattedValue = number(input, fractionSize);

      //get the decimalSepPosition
      var decimalIdx = formattedValue.indexOf(formats.DECIMAL_SEP);
      
      //If no decimal just return
      if (decimalIdx == -1) return formattedValue;

 
      var whole = formattedValue.substring(0, decimalIdx);
      var decimal = (Number(formattedValue.substring(decimalIdx)) || "").toString();
      
      return whole +  decimal.substring(1);
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <div ng-repeat="i in myList">{{i | numberEx:2}}</div>
</div>

【讨论】:

  • 嗯其实很酷。必须考虑一分钟才能弄清楚它为什么有效。
  • "*1" 和 "-0" 是在几乎任何脚本语言中转换数字类型的便捷方法,无需知道具体的内置方法来显式执行此操作。
  • 当数字大于 1000 时这不起作用,因为 angular 会为其添加逗号
  • @YangLi 提出了一个很好的观点。 Number(2000.5.toFixed(2))+2000.5.toFixed(2) 都从 Chrome 中的 Javascript 控制台评估为正确答案。但是,当我将它们嵌入到我的 Angular 模板中时,它们都不起作用。 (200.5 | number:2) * 1 通过我的模板工作,但由于杨丽提到的原因,2000.5 失败。
  • 这是因为数字过滤器将数字转换为字符串,如果它大于 1000,它会添加一个 , 给它。现在,当您执行 "1,200" * 1 时,它不会识别逗号。因此,您需要删除逗号或使用不会转换为带逗号的字符串的过滤器。
【解决方案2】:

我会这样做:

<div ng-repeat="i in myList">{{formatNumber(i)}}</div>

在你的控制器中:

$scope.formatNumber = function(i) {
    return Math.round(i * 100)/100; 
}

【讨论】:

  • 或返回+i.toFixed(2);
  • @dandavis 他说他不想要尾随零。
  • 必须在我的控制器中为这个简单的任务编写一个额外的函数似乎有点矫枉过正
  • 他的意思是他宁愿不写过滤器。 @SaqibAli 但是,使用角度的数字过滤器无法实现这一点。我假设您使用的是 {{(i | number:2)*1}},尝试将您的数字设置为 1000,您会遇到一些严重错误。
  • @inorganik:您在小提琴中遗漏了“+”。如果您使用我的代码,那么您将看到“2”...jsfiddle.net/deqrL4yw/1;不是错字;)
【解决方案3】:

由于其他答案效果不佳,或者没有合并或使用 Angular 的 $locale 服务,我写了以下filter

模板:

<span>{{yourNumber | roundTo: N}}</span>

过滤器:

app.filter('roundTo', function(numberFilter) {
    return function(value, maxDecimals) {
        return numberFilter((value || 0)
            .toFixed(maxDecimals)
            .replace(/(?:\.0+|(\.\d+?)0+)$/, "$1")
        );
    }
})

  • 将数字四舍五入到最大小数位数

  • 修剪所有尾随零

  • 在不需要时删除小数分隔符

  • 并且使用 Angular 的 $locale 格式

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 2015-11-12
    • 2014-06-11
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多