我尝试在Grails服务中使用g.render,但似乎默认情况下不会向服务提供g。有没有办法让模板引擎在服务中呈现视图?也许我的方法不对。我要做的是将局部模板的视图呈现为字符串,并将生成的字符串作为JSON响应的一部分发送回来,以便用于AJAX更新。
有什么想法吗?
我完全同意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。
使用PageRenderer在Grails 2中更加简单。例如:
class SomeService {
def groovyPageRenderer
void someMethod() {
String html = groovyPageRenderer.render(view: '/email/someTemplateName')
}
}
API - http://grails.org/doc/latest/api/grails/gsp/PageRenderer.html
更完整的示例 - http://mrhaki.blogspot.com/2012/03/grails-goodness-render-gsp-views-and.html
我的建议是在控制器中完成这个操作。服务应该具有可重用的逻辑,不依赖于视图模板,将这项工作留给控制器。使用服务获取需要传递给模板的数据,但将与模板交互的工作留给控制器。
这里有一个与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
}
}
createLink
,您需要指定controller
以及action
! - Charles Wood