Как сделать работу с отформатированным отформатированным индексом на последней версии AngularJS?
Я увидел это решение http://jsfiddle.net/gronky/GnTDJ/, и оно работает. То есть, когда вы вводите 25, он возвращается к модели как 0,25
HTML:
<script type="text/javascript" ng:autobind
src="http://code.angularjs.org/0.9.17/angular-0.9.17.js"></script>
<script>
function Main() {
this.var = '1.0000';
}
</script>
<div ng:controller="Main">
<input type="text" name="var" ng:format="percent">
<pre>var = {{var|json}}</pre>
</div>
JavaScript:
angular.formatter('percent', {
parse: function(value) {
var m = value.match(/^(\d+)\/(\d+)/);
if (m != null)
return angular.filter.number(parseInt(m[1])/parseInt(m[2]), 2);
return angular.filter.number(parseFloat(value)/100, 2);
},
format: function(value) {
return angular.filter.number(parseFloat(value)*100, 0);
},
});
Я попытался заставить его работать с последним AngularJS, он больше не работает, но http://jsfiddle.net/TrJcB/ То есть, когда вы вводите 25, также отбрасывается как 25, он не нажимает правильное значение 0,25 для модели.
Или, может быть, уже есть встроенный форматтер для процентов? Я тоже хотел форматировать форму или запятую.
Ответы
Ответ 1
Скрипка не работает с текущей версией Angular, так как с тех пор изменилось довольно много API. angular.formatter
больше не доступен и не является angular.filter
.
Теперь можно написать директиву и использовать $parser
и $formatter
доступные на контроллере директивы. Таким образом, ваша функция ссылки будет выглядеть примерно так
link: function(scope, ele, attr, ctrl){
ctrl.$parsers.unshift(
function(viewValue){
return $filter('number')(parseFloat(viewValue)/100, 2);
}
);
ctrl.$formatters.unshift(
function(modelValue){
return $filter('number')(parseFloat(modelValue)*100, 2);
}
);
}
Также фильтры теперь доступны через сервис $filter
. Вы можете найти документацию здесь: https://docs.angularjs.org/api/ng/filter/number
Обновленная скрипка для оригинального примера: http://jsfiddle.net/abhaga/DdeCZ/18/
Валютный фильтр уже доступен на английском языке: https://docs.angularjs.org/api/ng/filter/currency
Ответ 2
Другой способ реализации процентного фильтра (работает с angular # ~ 1.2):
angular.module('moduleName')
.filter('percentage', ['$filter', function($filter) {
return function(input, decimals) {
return $filter('number')(input*100, decimals)+'%';
};
}]);
Как использовать его:
<span>{{someNumber | percentage:2}}</span>
Ответ 3
Здесь приведена полная директива, которая будет анализировать, форматировать и выполнять валидацию Angular на входах. (Протестировано против Angular 1.2 и 1.3.)
Мы используем это, чтобы наша модель данных на/из сервера могла быть выражена в десятичной нотации (0.7634), но мы предоставляем пользователю понятный для пользователя формат (76.34) и обеспечиваем максимальную точность. Обратите внимание, что эта директива касается исключительно числовых аспектов. Мне легче вставить "%" в шаблон отдельно, а не включать его здесь.
По умолчанию используется принудительное ввод входных значений от -100 до 100, но вы можете предоставить свои собственные оценки с помощью attrs pct-min
и pct-max
.
'use strict';
angular.module('XLDirectives')
.directive('xlPercentage', function($filter) {
// A directive for both formatting and properly validating a percentage value.
// Assumes that our internal model is expressed as floats -1 to +1: .099 is 9.9%
// Formats display into percents 1-100, and parses user inputs down to the model.
// Parses user input as floats between 0 and 100 into floats less than 1.
// Validates user input to be within the range -100 to +100.
// Sets Angular $valid property accordingly on the ngModelController.
// If a `pct-max` or `pct-min` attribute is specified on the <input>, will use those bounds instead.
// If a `pct-decimals` attr present, will truncate inputs accordingly.
function outputFormatter(modelValue, decimals) {
var length = decimals || 2;
if (modelValue != null) {
return $filter('number')(parseFloat(modelValue) * 100, length);
} else {
return undefined;
}
};
function inputParser(viewValue, decimals) {
var length = decimals || 4;
if (viewValue != null) {
return $filter('number')(parseFloat(viewValue) / 100, length);
} else {
return undefined;
}
}
function isWithinBounds(value, upper, lower) {
if (value >= lower && value <= upper) {
return true;
} else {
return false;
}
}
return {
restrict: 'A',
require: 'ngModel',
link: function postLink(scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
// confirm the input from the view contains numbers, before parsing
var numericStatus = viewValue.match(/(\d+)/),
min = parseFloat(attrs.pctMin) || -100,
max = parseFloat(attrs.pctMax) || 100,
decimals = parseFloat(attrs.pctDecimals) || 4,
bounded = isWithinBounds(viewValue, max, min);
if (numericStatus !== null && bounded) {
ctrl.$setValidity('percentage', true);
// round to max four digits after decimal
return inputParser(viewValue, decimals);
} else {
ctrl.$setValidity('percentage', false);
return undefined
}
});
ctrl.$formatters.unshift(outputFormatter);
// we have to watch for changes, and run the formatter again afterwards
element.on('change', function(e) {
var element = e.target;
element.value = outputFormatter(ctrl.$modelValue, 2);
});
}
};
});
// REFS:
// http://stackoverflow.com/questions/17344828/angularjs-should-i-use-a-filter-to-convert-integer-values-into-percentages
// http://stackoverflow.com/questions/13668440/how-to-make-a-percent-formatted-input-work-on-latest-angularjs
Ответ 4
Я изменил ответ абхага, чтобы разрешить. ## и ## input. По-моему, это намного удобнее
link: function(scope, element, attr, ngModel) {
ngModel.$parsers.unshift(
function(viewValue){
var perc = parseFloat(viewValue);
if (perc<0 || perc>100 || !isFinite(perc)){
return null;
}
if (perc>1 && perc<=100){
return parseFloat($filter('number')(perc/100));
}
return perc;
}
);
ngModel.$formatters.unshift(
function(modelValue){
if(!isFinite(modelValue)){
return "";
}
return $filter('number')(parseFloat(modelValue)*100, 2);
}
);
}