AngularJS绑定中的数学函数

ric*_*ick 232 angularjs

有没有办法在AngularJS绑定中使用数学函数?

例如

<p>The percentage is {{Math.round(100*count/total)}}%</p>
Run Code Online (Sandbox Code Playgroud)

这个小提琴显示了这个问题

http://jsfiddle.net/ricick/jtA99/1/

Tos*_*osh 326

你必须注入Math你的范围,如果你需要使用它,因为 $scope对数学一无所知.

最简单的方法,你可以做到

$scope.Math = window.Math;
Run Code Online (Sandbox Code Playgroud)

在你的控制器中.正确的角度方法是创建一个Math服务,我想.

  • 您应该使用过滤器,而不是将Math对象放在范围上. (48认同)
  • 这对快速和肮脏的东西有好处; 快速嘲笑某事或想要看看事情是如何起作用的.这可能是想要在他们的html模板文件中做数学的人想要的. (4认同)

And*_*icz 304

虽然接受的答案是正确的,你可以注入Math以角度使用它,对于这个特殊的问题,更常规/角度的方式是数字过滤器:

<p>The percentage is {{(100*count/total)| number:0}}%</p>
Run Code Online (Sandbox Code Playgroud)

您可以在number此处阅读有关过滤器的更多信息:http://docs.angularjs.org/api/ng/filter/number

  • 安德鲁,很抱歉这篇评论让你的帖子变得杂乱无章.你的答案很好,很有帮助; 但是,我不同意其他意见.当人们吹捧"棱角分明的方式"时,我常常畏缩,好像它是完美发展的一些典范.事实并非如此.OP总体上询问如何在绑定中包含数学函数,仅将舍入作为示例.虽然这个答案可能是纯粹主义者解决一个数学问题的"棱角分明的方式",但它并没有完全回答这个问题. (39认同)
  • 这不仅是Angular的方式,而且是正确的方式.视图是"格式化"价值的责任. (7认同)

小智 61

我认为最好的方法是创建一个过滤器,如下所示:

myModule.filter('ceil', function() {
    return function(input) {
        return Math.ceil(input);
    };
});
Run Code Online (Sandbox Code Playgroud)

然后标记看起来像这样:

<p>The percentage is {{ (100*count/total) | ceil }}%</p>
Run Code Online (Sandbox Code Playgroud)

更新小提琴:http://jsfiddle.net/BB4T4/


Ben*_*esh 37

这是一个毛茸茸的回答,因为你没有给出你正在做的事情的完整背景.接受的答案是有效的,但在某些情况下会导致性能不佳.那,并且它将更难测试.

如果您将此作为静态表单的一部分,那很好.接受的答案将起作用,即使它不容易测试,也很容易.

如果你想成为"Angular":

您需要保留任何"业务逻辑"(即改变要显示的数据的逻辑).这样您就可以对逻辑进行单元测试,因此您最终不会将控制器与视图紧密耦合.从理论上讲,您应该能够将控制器指向另一个视图并使用范围中的相同值.(如果这是有道理的).

您还需要考虑在每个摘要必须对绑定内部的任何函数调用(例如{{}}ng-bindng-bind-html)进行评估,因为angular无法知道值是否已更改,就像它对属性一样在范围上.

执行此操作的"有角度"方式是使用ng-change事件甚至是$ watch将值中的值缓存在更改范围内.

例如,使用静态表单:

angular.controller('MainCtrl', function($scope, $window) {
   $scope.count = 0;
   $scope.total = 1;

   $scope.updatePercentage = function () {
      $scope.percentage = $window.Math.round((100 * $scope.count) / $scope.total);
   };
});
Run Code Online (Sandbox Code Playgroud)
<form name="calcForm">
   <label>Count <input name="count" ng-model="count" 
                  ng-change="updatePercentage()"
                  type="number" min="0" required/></label><br/>
   <label>Total <input name="total" ng-model="total"
                  ng-change="updatePercentage()"
                  type="number" min="1" required/></label><br/>
   <hr/>
   Percentage: {{percentage}}
</form>
Run Code Online (Sandbox Code Playgroud)

现在你可以测试它!

describe('Testing percentage controller', function() {
  var $scope = null;
  var ctrl = null;

  //you need to indicate your module in a test
  beforeEach(module('plunker'));

  beforeEach(inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();

    ctrl = $controller('MainCtrl', {
      $scope: $scope
    });
  }));

  it('should calculate percentages properly', function() {
    $scope.count = 1;
    $scope.total = 1;
    $scope.updatePercentage();
    expect($scope.percentage).toEqual(100);

    $scope.count = 1;
    $scope.total = 2;
    $scope.updatePercentage();
    expect($scope.percentage).toEqual(50);

    $scope.count = 497;
    $scope.total = 10000;
    $scope.updatePercentage();
    expect($scope.percentage).toEqual(5); //4.97% rounded up.

    $scope.count = 231;
    $scope.total = 10000;
    $scope.updatePercentage();
    expect($scope.percentage).toEqual(2); //2.31% rounded down.
  });
});
Run Code Online (Sandbox Code Playgroud)

  • @Neel - $ window允许您更轻松地模拟测试的"数学".另外,你可以创建一个Math服务并注入它. (3认同)

kla*_*xon 8

更好的选择是使用:

{{(100*score/questionCounter) || 0 | number:0}}
Run Code Online (Sandbox Code Playgroud)

在未初始化值的情况下,它将方程的默认值设置为0.


小智 8

为什么不将整个数学obj包装在过滤器中?

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


function math() {
    return function(input,arg) {
        if(input) {
            return Math[arg](input);
        }

        return 0;
    }
}

return app.filter('math',[math]);
Run Code Online (Sandbox Code Playgroud)

并使用:

{{number_var | 数学: '小区'}}


Got*_*urz 6

如果您想在Angular中进行简单的舍入,可以在表达式中轻松设置过滤器.例如:

{{ val | number:0 }}

请参阅此CodePen示例和其他数字过滤器选项.

关于使用数字过滤器的Angular Docs


Sar*_*rón 6

使用Angular进行简单数学运算的最简单方法是直接在HTML标记中根据需要进行单独绑定,假设您不需要在页面上进行质量计算.这是一个例子:

{{(data.input/data.input2)| number}} 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您只需在()中进行数学运算,然后使用过滤器| 得到一个答案.这里有关于将角度数字格式化为文本的更多信息:

https://docs.angularjs.org/api/ng/filter


小智 5

要么将全局 Math 对象绑定到作用域上(记住使用 $window 而不是 window)

$scope.abs = $window.Math.abs;
Run Code Online (Sandbox Code Playgroud)

在 HTML 中使用绑定:

<p>Distance from zero: {{abs(distance)}}</p>
Run Code Online (Sandbox Code Playgroud)

或者为您所追求的特定数学函数创建一个过滤器:

module.filter('abs', ['$window', function($window) {
  return function(n) {
    return $window.Math.abs($window.parseInt(n));
  };
});
Run Code Online (Sandbox Code Playgroud)

在 HTML 中使用过滤器:

<p>Distance from zero: {{distance | abs}}</p>
Run Code Online (Sandbox Code Playgroud)