2008-10-20 5 views

답변

1

내가에 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 
    } 
} 
+0

@ankimal - 다른 사람에 대해 언급하기에 충분한 담당자가 없습니다 - 당신이 시도가 :이
http://www.grails.org/Contribute+a+Tag#remotePaginate

합니까를 일부 유형의 결함이 있거나 사용자 정의 태그가 특정 작업에 특별히 적합합니까? –

1

나는 "3 일 전", "30 초 전"등의 상대 날짜를 툴팁으로 실시간 제공 해주는 "fmt : relDate"태그가 있습니다.

현재 구현은 기본적으로 if/then 문이 내가 좋아하는 경계가있는 거대한 체인입니다. 이진 검색 기반 알고리즘은 ("보다 효율적"이라는 의미에서) 더 좋을 것이고, 현재 구현에는 내 개인 기본 설정이 인코딩되어 있으므로 태그를 공유하지 않을 것입니다.

1

원격 페이지 매김 탭이있어 아약스를 통해 결과에 페이지 매김을 할 수 있습니다. 그것은 기본 탭을 개선하고 사용자 정의 인수를 취합니다. 여기

코드입니다 :

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')) 
     } 
    } 

    } 
관련 문제