在Grails中通过g:set

时间:2018-01-18 20:55:32

标签: grails views taglib

我正在使用grail 2.3.3并且我正在尝试将HTML值分配给自定义tagLib的返回值。我尝试了很多方法但没有成功。

正在发生的是正确的输出显示在网页上(因此tagLib的逻辑正常)但我需要的单个值没有被传递给'var'organId。

在这里查看了各种早期帖子是我在视图gsp文件中到目前为止所厌倦的事情:

       <g:returnLoginInfo loginId="${loginId}" fieldName="organId">
            <g:set var="organId" value="${0}" scope="flash" />
        </g:returnLoginInfo>

我还尝试将value =“$ {it}”作为默认参数,引用从tagLib传递的值。在tagLib中,我尝试通过“out&lt;&lt;”返回单个值,并尝试添加该行的返回值:

    static returnObjectForTags = ['returnLoginInfo'] 

确保tagLib可以返回值,而不是直接发送文本。

视图gsp文件中的另一种方法是:

  <g:set var="organId" value="${bind.returnLoginInfo(loginId="${loginId}" fieldName="organId")}"/>

我欢迎任何建议。

这是tagLib:

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” - 我认为这是因为它无法解析过滤器而只是假设currentLoginDetails是html中未定义的值。

或直接来自服务:

            <p> ${grailsApplication.mainContext.getBean("hvLoginDetailsService").myLoginDetails()}</p>

失败并显示错误:

  

没有定义名为'HvLoginDetailsS​​ervice'的bean

此致

麦克

1 个答案:

答案 0 :(得分:1)

如果您只需要从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>

更新:

将taglib定义为:

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>