在Grails服务中使用g.render

19

我尝试在Grails服务中使用g.render,但似乎默认情况下不会向服务提供g。有没有办法让模板引擎在服务中呈现视图?也许我的方法不对。我要做的是将局部模板的视图呈现为字符串,并将生成的字符串作为JSON响应的一部分发送回来,以便用于AJAX更新。

有什么想法吗?


对于那些多年后偶然发现这个页面的搜索者,请不要忘记,从服务中呈现模板意味着该模板没有与从控制器呈现时相同的上下文;因此,如果您在GSP中使用createLink,您需要指定controller以及action - Charles Wood
4个回答

28

我完全同意John的论点——在服务中进行GSP通常是一个不好的设计决策。但没有规则是没有例外的!如果你仍然想这样做,可以尝试以下方法:

class MyService implements InitializingBean {
    boolean transactional = false
    def gspTagLibraryLookup  // being automatically injected by spring
    def g

    public void afterPropertiesSet() {
        g = gspTagLibraryLookup.lookupNamespaceDispatcher("g")
        assert g
    }

    def serviceMethod() {    
       // do anything with e.g. g.render
    }
}

通过使用gspTagLibraryLookup bean,您当然可以在服务中访问每个其他所需的taglib。


伟大的力量伴随着巨大的责任!在做这样的事情时要小心 - 确保在将GSP呈现为服务之前了解其背后的原因 :) - Chii
我的意图是渲染一个模板,然后返回JSON,以便插入生成的HTML。我本来想将逻辑封装在服务中,但发现在每个控制器中手动返回JSON同样有效,并且g.render已经可用。感谢大家的建议。 - aasukisuki
它还有另一个问题...如果服务依赖于控制器,那么为这些服务创建单元测试就更加困难。 - luiscolorado
我需要从单个入口服务返回一些HTML(类似于命令模式)。这非常方便。非常感谢。 - Guillaume

16

差点错过了你的回答,感谢你添加它。现在使用新的Grails看起来很顺畅。 - moeTi
简单易懂。但是Stefan的回答提供了任何标签的解决方案。谢谢 ;) - IgniteCoders

4

我的建议是在控制器中完成这个操作。服务应该具有可重用的逻辑,不依赖于视图模板,将这项工作留给控制器。使用服务获取需要传递给模板的数据,但将与模板交互的工作留给控制器。


1
抱歉,即使您的回答是一个好建议,它也不是一个可接受的答案:虽然不被推荐,但有方法可以实现所要求的。 - Guillaume

3

这里有一个与Stefan类似但更简单的解决方案。

import org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware

class MyService implements ApplicationContextAware {

    private ApplicationTagLib g

    void setApplicationContext(ApplicationContext applicationContext) {
        g = applicationContext.getBean(ApplicationTagLib)

        // now you have a reference to g that you can call render() on
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接