我使用Angular"货币"过滤以显示购物车中的价格。价格从后端服务器获取。因此,有时可能无法向用户显示价格。在这种情况下,我只想向用户显示价格与货币字段在同一字段中不可用。我无法在货币过滤器中显示纯文本。我找到的唯一解决方案是在价格不可用时保持另一个文本字段显示/隐藏。但这是我认为不必要的。有没有办法扩展或覆盖内置的"货币" Angular js过滤器?请欣赏一些帮助。
<div class="large-12 medium-12 small-12 columns pad-none nzs-pro-list-item-price">
{{item.ItmPrice|currency}}
</div>
答案 0 :(得分:1)
创建自定义过滤器,当值存在时,内部将使用货币,否则它将返回您要显示的text
。
<强>标记强>
{{amount | customFormat:"USD$": "N/A"}}
过滤强>
.filter('customFormat', function($filter) {
return function(value, format, text) {
if (angular.isDefined(value) && value != null)
return $filter('currency')(value, format);
else
return text;
}
});
答案 1 :(得分:0)
我认为最好的方法是重写货币过滤器,以便您可以对模式,分组分隔符,小数分隔符和&amp;符号位置
<span>
{{26666662.5226 | fmtCurrency :"##.###,###" : "." : "," : "$" : "first"}}
</span>
重新开始: $ 26.666.662,523
过滤强>:
app.filter("fmtCurrency", ['CurrencyService', function sasCurrency(CurrencyService) {
return function (amount, pattern, groupingSeparator, decimalSeparator, currencySymbol, symbolPosition) {
var patternInfo = CurrencyService.parsePattern(pattern, groupingSeparator, decimalSeparator);
var formattedCurrency = CurrencyService.formatCurrency(amount, patternInfo, groupingSeparator, decimalSeparator);
if (symbolPosition === 'last')
return formattedCurrency + currencySymbol;
else
return currencySymbol + formattedCurrency;
};
}])
服务:formatNumber与角度货币过滤器中使用的功能相同,此处正在服务中使用
app.service("CurrencyService", function () {
var PATTERN_SEP = ';',
DECIMAL_SEP = '.',
GROUP_SEP = ',',
ZERO = '0',
DIGIT = "#";
var MAX_DIGITS = 22;
var ZERO_CHAR = '0';
return {
parsePattern: function (pattern, groupingSeparator, decimalSeparator) {
return parsePattern(pattern, groupingSeparator, decimalSeparator);
},
formatCurrency: function (amount, patternInfo, groupingSeparator, decimalSeparator) {
return formatNumber(amount, patternInfo, groupingSeparator, decimalSeparator);
}
}
/*
* Currency formatter utility
*/
function isUndefined(value) { return typeof value === 'undefined'; }
/**
* main function for parser
* @param str {string} pattern to be parsed (e.g. #,##0.###).
*/
function parsePattern(pattern, groupSep, decimalSep) {
DECIMAL_SEP = decimalSep;
GROUP_SEP = groupSep;
var p = {
minInt: 1,
minFrac: 0,
maxFrac: 0,
posPre: '',
posSuf: '',
negPre: '',
negSuf: '',
gSize: 0,
lgSize: 0
};
var ZERO = '0',
DIGIT = "#";
var parts = pattern.split(PATTERN_SEP),
positive = parts[0],
negative = parts[1];
var parts = positive.split(DECIMAL_SEP),
integer = parts[0],
fraction = parts[1];
console.log(parts);
p.posPre = integer.substr(0, integer.indexOf(DIGIT));
if (fraction) {
for (var i = 0; i < fraction.length; i++) {
var ch = fraction.charAt(i);
console.log(ch, ZERO, DIGIT);
if (ch == ZERO)
p.minFrac = p.maxFrac = i + 1;
else if (ch == DIGIT)
p.maxFrac = i + 1;
else
p.posSuf += ch;
}
}
var groups = integer.split(GROUP_SEP);
p.gSize = groups[1] ? groups[1].length : 0;
p.lgSize = (groups[2] || groups[1]) ? (groups[2] || groups[1]).length : 0;
if (negative) {
var trunkLen = positive.length - p.posPre.length - p.posSuf.length,
pos = negative.indexOf(DIGIT);
p.negPre = negative.substr(0, pos).replace(/\'/g, '');
p.negSuf = negative.substr(pos + trunkLen).replace(/\'/g, '');
} else {
// hardcoded '-' sign is fine as all locale use '-' as MINUS_SIGN. (\u2212 is the same as '-')
p.negPre = '-' + p.posPre;
p.negSuf = p.posSuf;
}
return p;
}
function isString(value) { return typeof value === 'string'; }
function isNumber(value) { return typeof value === 'number'; }
/**
* Format a number into a string
* @param {number} number The number to format
* @param {{
* minFrac, // the minimum number of digits required in the fraction part of the number
* maxFrac, // the maximum number of digits required in the fraction part of the number
* gSize, // number of digits in each group of separated digits
* lgSize, // number of digits in the last group of digits before the decimal separator
* negPre, // the string to go in front of a negative number (e.g. `-` or `(`))
* posPre, // the string to go in front of a positive number
* negSuf, // the string to go after a negative number (e.g. `)`)
* posSuf // the string to go after a positive number
* }} pattern
* @param {string} groupSep The string to separate groups of number (e.g. `,`)
* @param {string} decimalSep The string to act as the decimal separator (e.g. `.`)
* @param {[type]} fractionSize The size of the fractional part of the number
* @return {string} The number formatted as a string
*/
function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
if (!(isString(number) || isNumber(number)) || isNaN(number)) return '';
var isInfinity = !isFinite(number);
var isZero = false;
var numStr = Math.abs(number) + '',
formattedText = '',
parsedNumber;
if (isInfinity) {
formattedText = '\u221e';
} else {
parsedNumber = parse(numStr, '.');
roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);
var digits = parsedNumber.d;
var integerLen = parsedNumber.i;
var exponent = parsedNumber.e;
var decimals = [];
isZero = digits.reduce(function (isZero, d) { return isZero && !d; }, true);
// pad zeros for small numbers
while (integerLen < 0) {
digits.unshift(0);
integerLen++;
}
// extract decimals digits
if (integerLen > 0) {
decimals = digits.splice(integerLen, digits.length);
} else {
decimals = digits;
digits = [0];
}
// format the integer digits with grouping separators
var groups = [];
if (digits.length >= pattern.lgSize) {
groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));
}
while (digits.length > pattern.gSize) {
groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));
}
if (digits.length) {
groups.unshift(digits.join(''));
}
formattedText = groups.join(groupSep);
// append the decimal digits
if (decimals.length) {
formattedText += decimalSep + decimals.join('');
}
if (exponent) {
formattedText += 'e+' + exponent;
}
}
if (number < 0 && !isZero) {
return pattern.negPre + formattedText + pattern.negSuf;
} else {
return pattern.posPre + formattedText + pattern.posSuf;
}
}
function parse(numStr, decimalSep) {
var exponent = 0, digits, numberOfIntegerDigits;
var i, j, zeros;
DECIMAL_SEP = decimalSep;
// Decimal point?
if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {
numStr = numStr.replace(DECIMAL_SEP, '');
}
// Exponential form?
if ((i = numStr.search(/e/i)) > 0) {
// Work out the exponent.
if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;
numberOfIntegerDigits += +numStr.slice(i + 1);
numStr = numStr.substring(0, i);
} else if (numberOfIntegerDigits < 0) {
// There was no decimal point or exponent so it is an integer.
numberOfIntegerDigits = numStr.length;
}
// Count the number of leading zeros.
for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) {/* jshint noempty: false */ }
if (i === (zeros = numStr.length)) {
// The digits are all zero.
digits = [0];
numberOfIntegerDigits = 1;
} else {
// Count the number of trailing zeros
zeros--;
while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;
// Trailing zeros are insignificant so ignore them
numberOfIntegerDigits -= i;
digits = [];
// Convert string to array of digits without leading/trailing zeros.
for (j = 0; i <= zeros; i++ , j++) {
digits[j] = +numStr.charAt(i);
}
}
// If the number overflows the maximum allowed digits then use an exponent.
if (numberOfIntegerDigits > MAX_DIGITS) {
digits = digits.splice(0, MAX_DIGITS - 1);
exponent = numberOfIntegerDigits - 1;
numberOfIntegerDigits = 1;
}
return { d: digits, e: exponent, i: numberOfIntegerDigits };
}
/**
* Round the parsed number to the specified number of decimal places
* This function changed the parsedNumber in-place
*/
function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
var digits = parsedNumber.d;
var fractionLen = digits.length - parsedNumber.i;
// determine fractionSize if it is not specified; `+fractionSize` converts it to a number
fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize;
// The index of the digit to where rounding is to occur
var roundAt = fractionSize + parsedNumber.i;
var digit = digits[roundAt];
if (roundAt > 0) {
// Drop fractional digits beyond `roundAt`
digits.splice(Math.max(parsedNumber.i, roundAt));
// Set non-fractional digits beyond `roundAt` to 0
for (var j = roundAt; j < digits.length; j++) {
digits[j] = 0;
}
} else {
// We rounded to zero so reset the parsedNumber
fractionLen = Math.max(0, fractionLen);
parsedNumber.i = 1;
digits.length = Math.max(1, roundAt = fractionSize + 1);
digits[0] = 0;
for (var i = 1; i < roundAt; i++) digits[i] = 0;
}
if (digit >= 5) {
if (roundAt - 1 < 0) {
for (var k = 0; k > roundAt; k--) {
digits.unshift(0);
parsedNumber.i++;
}
digits.unshift(1);
parsedNumber.i++;
} else {
digits[roundAt - 1]++;
}
}
// Pad out with zeros to get the required fraction length
for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
// Do any carrying, e.g. a digit was rounded up to 10
var carry = digits.reduceRight(function (carry, d, i, digits) {
d = d + carry;
digits[i] = d % 10;
return Math.floor(d / 10);
}, 0);
if (carry) {
digits.unshift(carry);
parsedNumber.i++;
}
}
})
答案 2 :(得分:0)
$provide.decorator('currencyFilter', ['$delegate',
function ($delegate) {
var crncyFilter = $delegate;
var extendsFilter = function () {
var res = crncyFilter.apply(this, arguments);
if (arguments[2]) {
var digi1 = arguments[2] || 2;
return arguments[1] + Number(arguments[0]).toFixed(digi1);
}
else {
if (arguments[1] == "¥") {
return arguments[1] + Number(arguments[0]).toFixed(1);
}
}
};
return extendsFilter;
}]);
这是覆盖十进制数字的方法