Grails提供的CountryTagLib
有一个(过时的)国家/地区列表
class CountryTagLib {
static final ISO3166_3 = [
"scg":"Serbia and Montenegro",
"zmb":"Zambia"
]
}
我想更新此地图,以塞尔维亚和黑山的每个条目取代“塞尔维亚和黑山”条目。
我不能简单地update the contents of the Map或use metaprogramming,因为ISO3166_3
的内容会被复制到静态初始化程序中的其他变量
static {
ISO3166_3.each { k, v ->
COUNTRY_CODES_BY_NAME[v] = k
}
}
我需要在此静态初始化程序运行之前修改ISO3166_3
的代码。我认为没有任何办法可以实现这一点,所以我只留下了将整个CountryTagLib
复制粘贴到自定义标记库并在其中修改ISO3166_3
的难以接受的选项。我还必须更改每个<g:countrySelect>
以使用我的代码。我真的不想这样做....
答案 0 :(得分:2)
为什么不直接访问地图?该字段为final
,这意味着您无法修改字段本身,但不能修改其内容:
你做不到:
CountryTagLib.ISO3166_3 = xxxx // this will fail (final)
但这应该有效:
CountryTagLib.ISO3166_3.remove('scg')
..etc...
答案 1 :(得分:2)
严的方法是最干净的IMO,但供将来参考;在metaClass覆盖中链回到替换方法的一种方法是将旧方法存储在某处,然后在新方法中调用它:
class CountryTagLib {
static final ISO3166_3 = [
"scg":"Serbia and Montenegro",
"zmb":"Zambia"
]
}
// Get a handle to our old static getISO3166_3 method
def originalGetter = CountryTagLib.metaClass.getStaticMetaMethod( 'getISO3166_3', [] as Object[] )
CountryTagLib.metaClass.static.getISO3166_3 = {
// Call the old method, and manipulate the map it returns
originalGetter.invoke( delegate, null ).with {
remove('scg')
put( 'srb', 'Serbia' )
put( 'mon', 'Montenegro' )
it
}
}