내 프로젝트에서 태그를 사용하고 있습니다. grails.org의 맞춤 태그를 탐색하여 내 라이브러리에 대한 새로운 태그를 찾고있었습니다. StackOverflow의 커뮤니티에서 사람들이 공유하고 싶은 좋아하는 사용자 정의 태그가있는 경우좋아하는 사용자 정의 Grails 태그가 있습니까?
http://www.grails.org/Contribute+a+Tag
가 궁금했다.
내 프로젝트에서 태그를 사용하고 있습니다. grails.org의 맞춤 태그를 탐색하여 내 라이브러리에 대한 새로운 태그를 찾고있었습니다. StackOverflow의 커뮤니티에서 사람들이 공유하고 싶은 좋아하는 사용자 정의 태그가있는 경우좋아하는 사용자 정의 Grails 태그가 있습니까?
http://www.grails.org/Contribute+a+Tag
가 궁금했다.
내가에 DecimalFormat 클래스를 찾을 수 있습니다 (그리고 Grails에의 formatNumber 확장하여 태그) 특정 사용 사례에 대한 불투명 조금, 나는 여전히 꽤 몇 가지를 할 수있는 합리적인 방법을 발견하지 않았습니다 적절한 형식 문자열을 생성하기 위해 추악한 사전 처리없이 기본 형식을 사용합니다. 몇 달 전에 형식 문자열을 구성하고 숫자 자체에 최소한의 처리를하는 간단한 숫자 서식 태그를 던졌습니다.
내가 원했던만큼 일반적이고 우아하지는 않습니다 (당시에는 필요한 것이 전부였습니다 - 초보 기본이지만 GSP에서 추악한 처리를 계속합니다). 읽기 쉽고, (즉, 순진한 if-elseif 슬롭 대신 스케일링 반복을 만들거나, 사용자가 맞춤형 스케일 마커를 전달할 수 있도록하거나, 사용자 정의 숫자 유효성 검사기를 매개 변수로 허용하는 등).
// 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
}
}
나는 "3 일 전", "30 초 전"등의 상대 날짜를 툴팁으로 실시간 제공 해주는 "fmt : relDate"태그가 있습니다.
현재 구현은 기본적으로 if/then 문이 내가 좋아하는 경계가있는 거대한 체인입니다. 이진 검색 기반 알고리즘은 ("보다 효율적"이라는 의미에서) 더 좋을 것이고, 현재 구현에는 내 개인 기본 설정이 인코딩되어 있으므로 태그를 공유하지 않을 것입니다.
원격 페이지 매김 탭이있어 아약스를 통해 결과에 페이지 매김을 할 수 있습니다. 그것은 기본 탭을 개선하고 사용자 정의 인수를 취합니다. 여기
코드입니다 :class CustomRemotePaginateTagLib {
static namespace = 'myTagLib'
/** * Creates next/previous links to support pagination for the current controller * * <g:paginate total="$ { Account.count() } " /> */
def remotePaginate = {attrs ->
def writer = out
if (attrs.total == null) throwTagError("Tag [remotePaginate] is missing required attribute [total]")
if (attrs.update == null) throwTagError("Tag [remotePaginate] is missing required attribute [update]")
def locale = RequestContextUtils.getLocale(request)
def total = attrs.total.toInteger()
def update = attrs.update
def action = (attrs.action ? attrs.action : (params.action ? params.action : "list"))
def controller = (attrs.controller ? attrs.controller : params.controller)
def offset = params.offset?.toInteger()
def max = params.max?.toInteger()
def maxsteps = (attrs.maxsteps ? attrs.maxsteps.toInteger() : 10)
if (!offset) offset = (attrs.offset ? attrs.offset.toInteger() : 0)
if (!max) max = (attrs.max ? attrs.max.toInteger() : 10)
def linkParams = [offset: offset - max, max: max]
if (params.sort) linkParams.sort = params.sort
if (params.order) linkParams.order = params.order
if (attrs.params) linkParams.putAll(attrs.params)
linkParams['action'] = action
linkParams['controller'] = controller
def linkTagAttrs = [url: "#"]
if (attrs.controller) { linkTagAttrs.controller = attrs.controller }
if (attrs.id != null) { linkTagAttrs.id = attrs.id }
// determine paging variables
def steps = maxsteps > 0
int currentstep = (offset/max) + 1
int firststep = 1
int laststep = Math.round(Math.ceil(total/max))
// display previous link when not on firststep
if (currentstep > firststep) {
linkTagAttrs.class = 'prevLink'
def prevOffset = linkParams.offset
def params = attrs.params ?: []
params.'offset' = prevOffset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) {
(attrs.prev ? attrs.prev : g.message(code: 'default.paginate.prev', default: 'Previous'))
}
}
// display steps when steps are enabled and laststep is not firststep
if (steps && laststep > firststep) {
linkTagAttrs.class = 'step'
// determine begin and endstep paging variables
int beginstep = currentstep - Math.round(maxsteps/2) + (maxsteps % 2)
int endstep = currentstep + Math.round(maxsteps/2) - 1
if (beginstep < firststep) {
beginstep = firststep
endstep = maxsteps
}
if (endstep > laststep) {
beginstep = laststep - maxsteps + 1
if (beginstep < firststep) {
beginstep = firststep
}
endstep = laststep
}
// display firststep link when beginstep is not firststep
if (beginstep > firststep) {
linkParams.offset = 0
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) { firststep.toString() }
writer << '<span class="step">..</span>'
}
// display paginate steps
(beginstep..endstep).each {i ->
if (currentstep == i) {
writer << "<span class=\"currentStep\">${i}</span>"
} else {
linkParams.offset = (i - 1) * max
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) { i.toString() }
}
}
// display laststep link when endstep is not laststep
if (endstep < laststep) {
writer << '<span class="step">..</span>'
linkParams.offset = (laststep - 1) * max
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) { laststep.toString() }
}
}
// display next link when not on laststep
if (currentstep < laststep) {
linkTagAttrs.class = 'nextLink'
linkParams.offset = offset + max
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) {
(attrs.next ? attrs.next : g.message(code: 'default.paginate.next', default: 'Next'))
}
}
}
@ankimal - 다른 사람에 대해 언급하기에 충분한 담당자가 없습니다 - 당신이 시도가 :이
http://www.grails.org/Contribute+a+Tag#remotePaginate
합니까를 일부 유형의 결함이 있거나 사용자 정의 태그가 특정 작업에 특별히 적합합니까? –