我正在使用grail2.3.3,我正在尝试为自定义tagLib的返回值分配一个HTML值。我尝试了许多方法,但没有成功。
正在发生的事情是网页上显示了正确的输出(因此 tagLib 的逻辑没问题),但我需要的单个值没有传递给 to 'var' organId。
查看了之前的各种帖子后,以下是到目前为止我在查看 gsp 文件中感到厌倦的事情:
<g:returnLoginInfo loginId="${loginId}" fieldName="organId">
<g:set var="organId" value="${0}" scope="flash" />
</g:returnLoginInfo>
我还尝试了 value="${it}" 作为引用从 tagLib 传递的值的默认 it 参数。在 tagLib 中,我尝试通过"out <<"返回单个值,以及尝试在添加行后返回:
static returnObjectForTags = ['returnLoginInfo']
这确保了 tagLib 可以返回值,而不是直接发送文本
。视图 gsp 文件中的另一种方法是:
<g:set var="organId" value="${bind.returnLoginInfo(loginId="${loginId}" fieldName="organId")}"/>
我欢迎任何建议。
这是标签库:
package homevu1
class ReturnLoginInfoTagLib {
//static defaultEncodeAs = 'html'
static defaultEncodeAs = [taglib:'html']
//static encodeAsForTags = [tagName: 'raw']
//static returnObjectForTags = ['returnLoginInfo'] // now expects a return statement rather than an out at the end
def returnLoginInfo = {attrs, body->
def loginId = attrs["loginId"]
def fieldName= attrs["fieldName"]
def tagName = "returnLoginInfo"
log.debug(" $tagName START loginId: $loginId fieldName: $fieldName")
def secUserInstance = SecUser.get(loginId)
log.debug(" $tagName secUser: $secUserInstance")
log.debug(" $tagName secUser id: $secUserInstance.id")
log.debug(" $tagName secUser role: $secUserInstance.role")
log.debug(" $tagName secUser organId: $secUserInstance.organId")
def returnValue
if (fieldName == "organId")
{
def organisationInstance= OrganisationShr.findByName(secUserInstance.organId)
returnValue = organisationInstance.id
}
log.debug(" $tagName returnValue: $returnValue")
//return returnValue
out << body(returnValue)
} // end returnLoginInfo
正如下面的 Jacob 所建议的,我尝试了两种从视图中调用此 tagLib 的方法:
<g:set var="organId" value="${g.returnLoginInfo(loginId:"${loginId}", fieldName:"organId")}" />
和
<g:returnLoginInfo loginId="${loginId}" fieldName="organId">
<g:set var="organId" value="${it}" />
</g:returnLoginInfo>
不太确定我应该如何为第一种方法编码 return 语句?
使用过滤器 - 更新 2:
这是服务(不确定我的返回值语法是否正确):
package homevu1
class HvLoginDetailsService {
def springSecurityService
def myLoginDetails() {
def serviceName = "myLoginDetails"
def returnValue = 0
log.debug(" $serviceName hello world: $returnValue")
return 'hello'
} // end returnLoginInfo
} // HvLoginDetailsService
下面是筛选器定义:
package homevu1
class HomeVuFiltersController {
def HvLoginDetailsService
def filters = {
loginFilters(controller:'*', action:'*') {
before = {
}
after = { Map model ->
model.currentLoginDetails = HvLoginDetailsService.myLoginDetails()
}
}
}
} //eof controller
最后,我在 html 网页中调用它:
通过过滤器:
<p> ${currentLoginDetails}</p>
这显示了页面,但无法显示此返回值"hello" - 我相信这是因为它无法解析过滤器,并且只是假设当前登录详细信息是 html 中未定义的值。
或直接从服务:
<p> ${grailsApplication.mainContext.getBean("hvLoginDetailsService").myLoginDetails()}</p>
此操作失败并显示错误:
没有定义名为"HvLoginDetailsService"的 bean
问候
话筒
如果你只需要从 taglib 中设置一个值(使用 Grails 2.5.0 测试),你必须让你的 TagLib 使用 out 变量,如下所示:
class DemoTagLib {
static defaultEncodeAs = [taglib:'html']
def stackOverflowExample = { attrs ->
out << "This is your value ${attrs.value}"
}
}
你可以在你的 gsp 中像这样使用它(两种方式都有效)
<g:set var="organId" value="${g.stackOverflowExample(value:'Hello Grails')}" />
<h1>organId = ${organId}</h1>
<h1>organId2 = ${g.stackOverflowExample(value:'Hi Grails')}</h1>
要让它像在你的第一个例子中一样工作,你可以按照这样的思路做一些事情,在你的 taglib 中引用 body 参数:
def anotherExample = { attrs, body ->
out << body('My new return value')
}
并在 GSP 中使用它:
<g:anotherExample>
<g:set var="myVariable" value="${it}" />
<h2>Hey: ${myVariable}</h2>
</g:anotherExample>
更新:
您的标签库定义为:
def returnLoginInfo = {attrs, body->
def loginId = attrs["loginId"]
def fieldName= attrs["fieldName"]
def tagName = "returnLoginInfo"
log.debug(" $tagName START loginId: $loginId fieldName: $fieldName")
/*
def secUserInstance = SecUser.get(loginId)
log.debug(" $tagName secUser: $secUserInstance")
log.debug(" $tagName secUser id: $secUserInstance.id")
log.debug(" $tagName secUser role: $secUserInstance.role")
log.debug(" $tagName secUser organId: $secUserInstance.organId")
*/
def returnValue = 10
if (fieldName == "organId")
{
// def organisationInstance= OrganisationShr.findByName(secUserInstance.organId)
returnValue = 20 //organisationInstance.id
}
log.debug(" $tagName returnValue: $returnValue")
//return returnValue
out << body(returnValue)
} // end returnLoginInfo
视图中的以下代码有效:
<g:returnLoginInfo loginId="${loginId}" fieldName="organId">
<g:set var="organId" value="${it}" />
</g:returnLoginInfo>
<h3>As taglib: organId = ${organId}</h3>
<g:returnLoginInfo loginId="${loginId}" fieldName="notOrganId">
<g:set var="organId" value="${it}" />
</g:returnLoginInfo>
<h3>As taglib: organId = ${organId}</h3>
为我提供 organId 的输出 20 和 10。
话虽如此,我不确定我是否会为您的用例使用 TagLib,我会使用服务,并通过控制器提供给视图的地图提供值。
更新 2:
以上内容已通过Grails 2.5.0进行验证。您的用例不像 TagLib 用例那样接缝,而您只想设置一个值。我会走向不同的方向。如果您不需要参数(因为它们可能来自会话或安全服务),过滤器将完成这项工作。
逻辑的服务可以是这样的:
@Transactional
class DemoService {
List<Integer> myServiceMethod(Integer i) {
if( i > 0) {
(1..i).collect { it }
} else {
[i]
}
}
}
你可以做一个这样的过滤器:
class MyFilterFilters {
DemoService demoService
def filters = {
all(controller:'*', action:'*') {
before = {
}
after = { Map model ->
model.myIdValue = demoService.myServiceMethod(5)
}
afterView = { Exception e ->
}
}
}
}
您可以直接在每个视图中访问 myIdValue:
<p> ${myIdValue}</p>
如果需要参数,可以直接从视图中使用服务(不推荐 - 但可能,并且不会比从 taglib 使用它对性能的影响更大):
<p> ${grailsApplication.mainContext.getBean("demoService").myServiceMethod(3)}</p>