Есть ли способ использовать математические функции в привязках AngularJS?
например.
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Эта скрипта показывает проблему
Есть ли способ использовать математические функции в привязках AngularJS?
например.
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Эта скрипта показывает проблему
Вам нужно ввести Math в свою область действия, если вам нужно использовать ее как
$scope ничего не знает о математике.
Простейший способ, вы можете сделать
$scope.Math = window.Math;
в вашем контроллере. Angular, чтобы сделать это правильно, я создаю Math-сервис.
В то время как принятый ответ прав, что вы можете ввести Math, чтобы использовать его в angular, для этой конкретной проблемы более обычным способом /angular является числовой фильтр:
<p>The percentage is {{(100*count/total)| number:0}}%</p>
Подробнее о фильтре number вы можете прочитать здесь: http://docs.angularjs.org/api/ng/filter/number
Я думаю, что лучший способ сделать это - создать фильтр, например:
myModule.filter('ceil', function() {
    return function(input) {
        return Math.ceil(input);
    };
});
тогда разметка выглядит следующим образом:
<p>The percentage is {{ (100*count/total) | ceil }}%</p>
Обновлен скрипт: http://jsfiddle.net/BB4T4/
Это волосатый ответ, потому что вы не дали полного контекста того, что вы делаете. Принятый ответ будет работать, но в некоторых случаях это приведет к низкой производительности. Это, и это будет труднее проверить.
Если вы делаете это как часть статической формы, отлично. Принятый ответ будет работать, даже если его нелегко проверить, и это неловко.
Вы хотите сохранить любую "бизнес-логику" (то есть логику, которая изменяет отображаемые данные) из ваших представлений. Это значит, что вы можете unit test использовать свою логику, и поэтому вы не будете плотно связывать ваш контроллер и ваше представление. Теоретически, вы должны указывать ваш контроллер на другое представление и использовать те же значения из областей. (если это имеет смысл).
Вы также захотите рассмотреть, что любые вызовы функций внутри привязки (например, {{}} или ng-bind или ng-bind-html) должны оцениваться на каждом дайджесте, потому что angular не имеет способа зная, изменилось ли значение или не понравилось это с свойством в области видимости.
"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);
   };
});
<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>
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.
  });
});
Лучше использовать:
{{(100*score/questionCounter) || 0 | number:0}}
Он устанавливает значение по умолчанию для уравнения равным 0 в случае, когда значения не инициализируются.
Самый простой способ сделать простую математику с помощью Angular - это непосредственно в разметке HTML для отдельных привязок по мере необходимости, предполагая, что вам не нужно делать массовые вычисления на своей странице. Вот пример:
{{(data.input/data.input2)| number}} 
В этом случае вы просто выполните математику в(), а затем используйте фильтр | чтобы получить номер ответа. Здесь больше информации о форматировании чисел Angular в виде текста:
Если вы хотите сделать простой раунд в Angular, вы можете легко установить фильтр внутри своего выражения. Например:
 {{ val | number:0 }}
Смотрите этот CodePen пример и для других параметров фильтра числа.
Почему бы не обернуть всю математику 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]);
и использовать:
{{number_var | математика: 'CEIL'}}
Либо привязать глобальный объект Math к области (не забудьте использовать $window not window)
$scope.abs = $window.Math.abs;
Используйте привязку в своем HTML:
<p>Distance from zero: {{abs(distance)}}</p>
Или создайте фильтр для конкретной математической функции, которую вы выполняете:
module.filter('abs', ['$window', function($window) {
  return function(n) {
    return $window.Math.abs($window.parseInt(n));
  };
});
Используйте фильтр в своем HTML:
<p>Distance from zero: {{distance | abs}}</p>
Это не похоже на способ Angular сделать это. Я не совсем уверен, почему он не работает, но вам, вероятно, потребуется получить доступ к области, чтобы использовать такую функцию.
Мое предложение было бы создать фильтр. Это способ Angular.
myModule.filter('ceil', function() {
    return function(input) {
        return Math.ceil(input);
    };
});
Затем в вашем HTML сделайте следующее:
<p>The percentage is {{ (100*count/total) | ceil }}%</p>
Это более или менее резюме трех ответов (Sara Inés Calderón, klaxon и Gothburz), но поскольку все они добавили что-то важное, я считаю целесообразным присоединиться к решениям и добавить еще несколько объяснений.
Учитывая ваш пример, вы можете делать вычисления в своем шаблоне, используя:
{{ 100 * (count/total) }}
Однако это может привести к большому количеству десятичных знаков, поэтому с использованием фильтров является хорошим способом:
{{ 100 * (count/total) | number }}
По умолчанию фильтр количества будет оставить до трех дробных цифр, здесь находится аргумент  fractionSize очень удобно
({{ 100 * (count/total) | number:fractionSize }}), что в вашем случае будет:
{{ 100 * (count/total) | number:0 }}
Это также будет округлять результат:
angular.module('numberFilterExample', [])
  .controller('ExampleController', ['$scope',
    function($scope) {
      $scope.val = 1234.56789;
    }
  ]);<!doctype html>
<html lang="en">
  <head>  
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  </head>
  <body ng-app="numberFilterExample">
    <table ng-controller="ExampleController">
      <tr>
        <td>No formatting:</td>
        <td>
          <span>{{ val }}</span>
        </td>
      </tr>
      <tr>
        <td>3 Decimal places:</td>
        <td>
          <span>{{ val | number }}</span> (default)
        </td>
      </tr>
      <tr>
        <td>2 Decimal places:</td>
        <td><span>{{ val | number:2 }}</span></td>
      </tr>
      <tr>
        <td>No fractions: </td>
        <td><span>{{ val | number:0 }}</span> (rounded)</td>
      </tr>
    </table>
  </body>
</html>Фильтр number форматирует число с разделителями тысяч, поэтому это не строго математическая функция.
Кроме того, его десятичный "лимитер" не ceil не нарезал десятичные числа (как некоторые другие ответы заставляют вас поверить), а скорее round их.
Итак, для любой математической функции, которую вы хотите, вы можете ввести ее (проще обмануть, чем впрыснуть весь объект Math) следующим образом:
myModule.filter('ceil', function () {
  return Math.ceil;
});
Не нужно также обертывать его другой функцией.