我無法解決這個問題的OOP方面。我的意思是我無法找到如何覆蓋閉包。我嘗試了幾種方法,但沒有成功。並且你不能覆蓋閉包的文檔says,你只能用新的實現來替換它(請糾正我,如果我錯了)。
但是(!)我能夠通過複製粘貼ApplicationTagLib#createLink方法的源代碼來解決任務。 我認爲這是殘酷的解決方案,但經過8個小時與這個簡單的任務作鬥爭 - 這是可以接受的。
所以最後所有我需要做的 - 是這個類定義,Grails將立即將其用於鏈接生成(對所有的意見,沒有必要改變他們的代碼):
import java.text.SimpleDateFormat;
import groovy.time.*;
import java.text.*;
import org.codehaus.groovy.grails.commons.GrailsControllerClass
import org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib;
import org.codehaus.groovy.grails.web.mapping.UrlCreator
import org.codehaus.groovy.grails.commons.ControllerArtefactHandler
import org.springframework.web.context.request.RequestContextHolder
class OverrideTagLib extends ApplicationTagLib {
def createLink = { attrs ->
// get value for regionId parameter
def regionId = regionIdFinderService.currentRegionId
// add cutsom regionId parameter
if (attrs) {
if (attrs.params)
attrs.params.put("regionId", regionId);
else {
attrs.params = ["regionId":regionId];
}
}
// process
def writer = getOut()
// prefer URI attribute
if (attrs.uri) {
writer << handleAbsolute(attrs)
writer << attrs.uri.toString()
}
else {
// prefer a URL attribute
def urlAttrs = attrs
if (attrs.url instanceof Map) {
urlAttrs = attrs.remove('url').clone()
}
else if (attrs.url) {
urlAttrs = attrs.remove('url').toString()
}
if (urlAttrs instanceof String) {
if (useJsessionId) {
writer << response.encodeURL(urlAttrs)
}
else {
writer << urlAttrs
}
}
else {
def controller = urlAttrs.containsKey("controller") ? urlAttrs.remove("controller")?.toString() : controllerName
def action = urlAttrs.remove("action")?.toString()
if (controller && !action) {
GrailsControllerClass controllerClass = grailsApplication.getArtefactByLogicalPropertyName(ControllerArtefactHandler.TYPE, controller)
String defaultAction = controllerClass?.getDefaultAction()
if (controllerClass?.hasProperty(defaultAction)) {
action = defaultAction
}
}
def id = urlAttrs.remove("id")
def frag = urlAttrs.remove('fragment')?.toString()
def params = urlAttrs.params && urlAttrs.params instanceof Map ? urlAttrs.remove('params') : [:]
def mappingName = urlAttrs.remove('mapping')
if (mappingName != null) {
params.mappingName = mappingName
}
if (request['flowExecutionKey']) {
params."execution" = request['flowExecutionKey']
}
if (urlAttrs.event) {
params."_eventId" = urlAttrs.remove('event')
}
def url
if (id != null) params.id = id
def urlMappings = applicationContext.getBean("grailsUrlMappingsHolder")
UrlCreator mapping = urlMappings.getReverseMapping(controller,action,params)
// cannot use jsessionid with absolute links
if (useJsessionId && !attrs.absolute) {
url = mapping.createURL(controller, action, params, request.characterEncoding, frag)
def base = attrs.remove('base')
if (base) writer << base
writer << response.encodeURL(url)
}
else {
url = mapping.createRelativeURL(controller, action, params, request.characterEncoding, frag)
writer << handleAbsolute(attrs)
writer << url
}
}
}
}
}
謝謝你的回答,但是這不會幫助,因爲兩個原因:1。 我不想更改所有視圖代碼; 2.更重要的是 - 當你想要指定參數值的時候,grails不夠聰明,其中一些是路徑元素和一些url參數。如果你將嘗試混合它們,grails會將它們全部作爲url參數傳遞。 – 2011-06-04 07:49:17
2.'URL映射的另一個強大功能是它們自動定製鏈接標記的行爲,以便更改映射不要求您去更改所有鏈接。這是通過URL重寫技術來完成的,該技術反向設計URL映射中的鏈接。所以給定一個映射,比如前面一節中的博客 - 從Grails文檔 – netbrain 2011-06-04 08:53:12