我正在使用Spring Security。假设我有User
属于Store
。 Store
有一个属性,用于确定是否有在线商店:
class Store {
...
boolean isOnline
...
}
class User {
...
def belongsTo = [ store: Store ]
...
}
在每个页面上显示的全局导航栏模板中,如果当前登录用户的Store
在线购物,我想显示一个链接。我目前正在工具栏模板中使用此代码:
<g:set var="userId" value="${sec.loggedInUserInfo(field: 'id') as Long}"/>
<g:set var="user" value="${User.get(userId)}"/>
<g:if test="${user.store.isOnline}">
<li>
<g:link controller="store" action="redirect">Shop Online</g:link>
</li>
</g:if>
虽然这段代码有效,但是有更好的方法来处理这个逻辑吗?我并不特别喜欢我正在为每个页面渲染执行此代码,我特别不喜欢我在视图中直接使用User.get()
。
换句话说,对于一个允许我抓住实际springSecurityService.currentUser
对象并沿着它的关系传播的视图,是否有等同于User
的内容?
答案 0 :(得分:0)
您可以将此逻辑移至过滤器:
class UserFilters {
SpringSecurityService springSecurityService
def filters = {
loadUser(controller: '*', action: '*') {
before = {
def user = springSecurityService.currentUser
request.setAttribute('currentUser', user)
}
}
}
}
因此,您可以在视图中使用currentUser
:
<g:if test="${currentUser.store.isOnline}">
...
</g:if>
有关过滤器的更多信息:http://grails.org/doc/latest/guide/theWebLayer.html#filters
答案 1 :(得分:0)
我建议将此逻辑移动到控制器并为该控制器准备视图(您用于导航栏的小块)。然后,您可以使用<g:include/>
标记重用该视图的控制器操作。
答案 2 :(得分:0)
.get()
通常会在点击数据库之前从二级缓存中提取,因此这不是我所关注的。逻辑的位置只是放错了地方。我会将您的视图逻辑放在自定义标记库中。