Чи існує спосіб використання математичних функцій у прив'язках AngularJS?
напр
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Ця скрипка показує проблему
private Math = Math;
і ви можете ним скористатися.
Чи існує спосіб використання математичних функцій у прив'язках AngularJS?
напр
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Ця скрипка показує проблему
private Math = Math;
і ви можете ним скористатися.
Відповіді:
Ви повинні вводити Math
в свою область, якщо вам потрібно використовувати її, оскільки
$scope
нічого не знаєте про Math.
Найпростіший спосіб, який ви можете зробити
$scope.Math = window.Math;
у вашому контролері. Кутовим способом зробити це правильно було б створити сервіс Math, я думаю.
formatting
, тому замість цього використовуйте фільтр.
Хоча прийнята відповідь правильна, що ви можете ввести Math
її в кутовій, для цієї конкретної проблеми більш звичайним / кутовим способом є фільтр чисел:
<p>The percentage is {{(100*count/total)| number:0}}%</p>
Докладніше про number
фільтр можна прочитати тут: http://docs.angularjs.org/api/ng/filter/number
{{1234.567|number:2}}
надає як 1,234.57
або 1 234,57
. Якщо ви спробуєте передати його, <input type="number" ng-value="1234.567|number:2">
ви введете порожнє введення, оскільки значення НЕ ПРАВИЛЬНА НОМЕРА, а представлення рядка, що залежить від локалу.
Я думаю, що найкращий спосіб це зробити, створивши такий фільтр:
myModule.filter('ceil', function() {
return function(input) {
return Math.ceil(input);
};
});
тоді розмітка виглядає так:
<p>The percentage is {{ (100*count/total) | ceil }}%</p>
Оновлена скрипка: http://jsfiddle.net/BB4T4/
На це відповісти волохатий, бо ви не дали повного контексту того, що робите. Прийнята відповідь спрацює, але в деяких випадках спричинить низьку ефективність. Це, і це буде важче перевірити.
Якщо ви робите це як частина статичної форми, добре. Прийнята відповідь спрацює, навіть якщо це непросто перевірити, і це химерно.
Ви хочете, щоб будь-яка "бізнес-логіка" (тобто логіка, яка змінює дані, що відображаються), поза вашими поглядами. Це так, що ви можете перевірити свою логіку, і щоб ви не закінчилися міцно з’єднати контролер і свій погляд. Теоретично, ви повинні мати змогу вказувати контролеру на інший вигляд і використовувати ті самі значення з областей. (якщо це має сенс).
Ви також хочете врахувати, що будь-які виклики функцій всередині прив'язки (наприклад, {{}}
або ng-bind
або ng-bind-html
) повинні бути оцінені під час кожного дайджесту , оскільки кутовий не має можливості знати, змінилося чи не так, як це було б у властивості про сферу застосування.
"Кутовим" способом зробити це було б кешування значення у властивості в області застосування при зміні за допомогою події зміни ng або навіть $ 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.
});
});
$window
оскільки, здається, працює з просто планом Math.round()
?
Math
тестами. Альтернативно, ви можете створити службу Math та ввести її.
Чому б не загорнути весь фільтр з математики у фільтр?
var app = angular.module('fMathFilters',[]);
function math() {
return function(input,arg) {
if(input) {
return Math[arg](input);
}
return 0;
}
}
return app.filter('math',[math]);
і використовувати:
{{номер_вар | математика: 'стеля'}}
Якщо ви хочете зробити простий раунд у куті, ви можете легко встановити фільтр всередині виразу. Наприклад:
{{ val | number:0 }}
Дивіться цей приклад CodePen та інші параметри фільтра чисел.
Найпростіший спосіб зробити просту математику за допомогою Angular - це безпосередньо розмітка HTML за індивідуальними прив'язками, якщо потрібно, припускаючи, що вам не потрібно робити масові обчислення на своїй сторінці. Ось приклад:
{{(data.input/data.input2)| number}}
У цьому випадку ви просто зробите математику в () і використовуєте фільтр | щоб отримати відповідь на номер. Ось додаткові відомості про форматування кутових чисел у вигляді тексту:
Або прив’яжіть глобальний об'єкт Math до області (не забудьте використовувати $ window not window)
$scope.abs = $window.Math.abs;
Використовуйте прив'язку у своєму HTML:
<p>Distance from zero: {{abs(distance)}}</p>
Або створіть фільтр для конкретної функції Math, яку ви виконуєте:
module.filter('abs', ['$window', function($window) {
return function(n) {
return $window.Math.abs($window.parseInt(n));
};
});
Використовуйте фільтр у своєму HTML:
<p>Distance from zero: {{distance | abs}}</p>
Це не схоже на дуже кутовий спосіб зробити це. Я не зовсім впевнений, чому це не працює, але вам, мабуть, знадобиться отримати доступ до області, щоб використовувати таку функцію.
Моєю пропозицією було б створити фільтр. Це кутовий шлях.
myModule.filter('ceil', function() {
return function(input) {
return Math.ceil(input);
};
});
Потім у своєму HTML зробіть це:
<p>The percentage is {{ (100*count/total) | ceil }}%</p>
number
Фільтр форматує число з тисячами роздільників, так що це не строго математична функція.
Більше того, його десятковий "обмежувач" - це не ceil
нарізані десяткові знаки (як деякі інші відповіді призведе до того, що ви повірите), а навпаки round
.
Отже, будь-яку математичну функцію, яку ви хочете, ви можете ввести її (простіше знущатися, ніж вводити весь об'єкт Math) так:
myModule.filter('ceil', function () {
return Math.ceil;
});
Не потрібно також перетворювати його на іншу функцію.
Це більш-менш резюме трьох відповідей (Сара Інес Калдерон, Клаксон та Готбурц), але оскільки всі вони додали щось важливе, я вважаю, що варто приєднатись до рішень та додати ще кілька пояснень.
Розглядаючи ваш приклад, ви можете робити розрахунки у своєму шаблоні, використовуючи:
{{ 100 * (count/total) }}
Однак це може призвести до безлічі десяткових знаків, тому використання фільтрів - хороший спосіб:
{{ 100 * (count/total) | number }}
За замовчуванням фільтр чисел залишить до трьох дробових цифр. Ось тут досить зручним є аргумент дробSize ( {{ 100 * (count/total) | number:fractionSize }}
), що у вашому випадку буде:
{{ 100 * (count/total) | number:0 }}
Це також окружить результат вже:
Останнє, що потрібно зазначити, якщо ви покладаєтесь на зовнішнє джерело даних, можливо, це хороша практика забезпечити належне резервне значення (інакше на вашому веб-сайті ви можете побачити NaN або нічого):
{{ (100 * (count/total) | number:0) || 0 }}
Sidenote: Залежно від ваших специфікацій, ви навіть можете бути більш точними з вашими резервними копіями / визначати запаси вже на нижчих рівнях (наприклад {{(100 * (count || 10)/ (total || 100) | number:2)}}
). Хоча це може не завжди мати сенс ..
Приклад кутового шрифту з використанням труби.
math.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'math',
})
export class MathPipe implements PipeTransform {
transform(value: number, args: any = null):any {
if(value) {
return Math[args](value);
}
return 0;
}
}
Додати до декларацій @NgModule
@NgModule({
declarations: [
MathPipe,
то використовуйте у своєму шаблоні так:
{{(100*count/total) | math:'round'}}
<p>The percentage is {{(100*count/total)| number:0}}%</p>
детальніше в коментарі нижче.