znajdę klasę DecimalFormat (i Grails męska formatNumber tag według rozszerzenia) nieco nieprzezroczysta dla pewnych przypadków użycia, a ja nadal nie znalazłem rozsądny sposób to zrobić jakiś ładny podstawowe formatowanie z nim bez brzydkiego wstępnego przetwarzania w celu wygenerowania odpowiedniego ciągu formatu. Kilka miesięcy temu zrzuciłem prosty tag do formatowania liczb, który zasadniczo tworzy ciąg formatujący i wykonuje minimalne przetwarzanie do samego numeru.
To nie jest tak ogólne i eleganckie jak bym chciała (to wszystko, czego potrzebowaliśmy w tym czasie - jest super podstawowe, ale nadal utrzymuje pewne brzydkie przetwarzanie z GSP), ale powinno być łatwe do odczytania, a to oczywiste, gdzie można go w prosty sposób usprawnić (np. uczynienie iteracji skalowania zamiast naiwnego if-elseif slop, pozwalając użytkownikowi na przekazanie niestandardowych znaczników skalowania, pozwalając na użycie niestandardowego walidatora liczb jako parametru itp.).
// Formats a number to 3 significant digits, appending appropriate scale marker
// (k, m, b, t, etc.). Defining var allows you to use a string representation
// of the formatted number anywhere you need it within the tag body, and
// provides the scale as well (in case highlighting or other special formatting
// based upon scale is desired).
def formatNumberScaled = {attrs, body -> // number, prefix, suffix, invalid, var
Double number
String numberString
String scale
try {
number = attrs.'number'.toDouble()
} catch (Exception e) {
number = Double.NaN
}
if (number.isNaN() || number.isInfinite()) {
numberString = scale = attrs.'invalid' ?: "N/A"
} else {
Boolean negative = number < 0d
number = negative ? -number : number
if (number < 1000d) {
scale = ''
} else if (number < 1000000d) {
scale = 'k'
number /= 1000d
} else if (number < 1000000000d) {
scale = 'm'
number /= 1000000d
} else if (number < 1000000000000d) {
scale = 'b'
number /= 1000000000d
} else if (number < 1000000000000000d) {
scale = 't'
number /= 1000000000000d
}
String format
if (number < 10d) {
format = '#.00'
} else if (number < 100d) {
format = '##.0'
} else {
format = '###'
}
format = "'${attrs.'prefix' ?: ''}'${format}'${scale} ${attrs.'suffix' ?: ''}'"
numberString = g.formatNumber('number': negative ? -number : number, 'format': format)
}
// Now, either print the number or output the tag body with
// the appropriate variables set
if (attrs.'var') {
out << body((attrs.'var'): numberString, 'scale': scale)
} else {
out << numberString
}
}
@ankimal - nie mają wystarczająco dużo rep skomentowania innych - czy próbowałeś:
http://www.grails.org/Contribute+a+Tag#remotePaginate
to ma niedobór jakiegoś typu, czy też niestandardowy tag jest specjalnie dopasowany do jakiegoś zadania? –