我需要访问main.gsp布局中的特定模型。我已经四处搜索并了解到,最好的方法是创建一个后过滤器并将模型应用于viewModel参数,然后在gsp中访问它,如下所示:
class MyFilters {
all(controller:'*', action:'*') {
after = {viewModel ->
viewModel.client = Client.get(session.clientId)
// println "Client is: ${client.toString()}"
}
}
}
在我的GSP中,我应该获得“客户端”并能够访问它?
<g:if test="${client.isPartner()}">
Do something
</g:if>
<g:else>
Do something else
</g:else>
我正在尝试做的一个例子是包括GSP模板,并根据当前登录的客户端是否属于合作伙伴包含特定的CSS样式表。特殊CSS和GSP模板的位置取决于合作伙伴名称,例如:
<g:if test="${client.isPartner()}">
<link rel="stylesheet" type="text/css" href="/partners/${client.getPartner().toString()}/css/style.css"/>
</g:if>
<g:else>
<link rel="stylesheet" type="text/css" href="/partners/default/css/style.css"/>
</g:else>
这也可以通过GSP模板完成......但是,每当我这样做时,我都会例外:
ERROR grails.web.pages.GroovyPagesServlet - Original exception : Cannot invoke method isPartner() on null object
因此,显然“客户”在GSP中为空。如果我在上面显示的后过滤器中取消注释println,则此时它不为空,并且打印客户端的名称。我在这里做错了吗?有没有更好的方法来获取main.gsp中的模型?
答案 0 :(得分:3)
这看起来像我最近回答的一个问题的副本。我建议用标签库解决这个问题:
您可以在标记库中访问会话,因此有点像这样的闭包应该有效:
...
static namespace = "yournamespace"
...
def partnerDetails = { attrs, body ->
def client = Client.get(session.clientId)
if (client.isPartner()) {
out << "Whatever you want to write out..."
// You can also call other tag libs from here - see docs
}
}
...
然后你在你的gsp中使用这样的标签:
<yournamespace:partnerDetails />
您还可以传递属性,这些属性通过attrs
地图传递到闭包中,如果这有用的话。
最后,如果你想有条件地渲染标签的主体,那么你可以这样做:
...
if (client.isPartner()) {
out << body()
}
....
你会这样称呼它:
<yournamespace:partnerDetails>
This is the body content that will be output in the body() call above.
</yournamespace:partnerDetails>
答案 1 :(得分:1)
该过滤器仅匹配通过控制器的请求。如果您直接路由到UrlMappings.groovy中的视图,则不会受到影响。尝试使用这样的方法来过滤网址,无论它们是否通过控制器进行路由。
class MyFilters {
all(uri: "/**") {
...
}
}
答案 2 :(得分:1)
我建议创建以下TagLib:
<g:ifPartner id="123">This client is a partner</g:ifPartner>
相应的代码看起来像这样:
def isPartner = { attrs, body ->
def id = attrs.remove('id')
if (Client.get(id)?.isPartner()) {
out << body()
}
}