视图存储在grails-app/views directory目录下。主要想学习如何创建Taglib和如何利用模板技术。
Grails使用GSP作为表现层,在GSP中groovy不只是表明GSP是基于什么技术的,而且还可以利用Groovy来创建一些脚本来在GSP中执行。在这点上说GSP和JSP很相像。
当然内嵌的脚本并不利于代码的重用。Grails中的Taglib和模板给你提供了一个很好的重用代码的途径。
GSP是Grails的视图的基础。List页面提供到Show页面的连接,Show页面允许你导航到Edit页面。
MVC的分离策略主要是可以给应用程序不同的视图,Grails通过不同的插件来支持不同的表现层技术。可以通过命令grails install-plugin来查看现在安装的插件。或使用grails list-plugins来获得当前可用的插件。
虽然Grails 并不支持 native和JSF,但是你还是可以使用他们。一个Grails程序就是一个标准的Java EE程序,因此只要你在lib目录中放置了正确的Jar文件,并在WEB-INF/web.xml文件中进行了正确的配置,就可以正常的使用了。Grails实在一个标准的servlet容器中开发的,所以Grails程序也支持JSP。
类似的增加Ajax框架也同样的简单,拷贝JavaScript库到web-app/js目录下。 Prototype和Scriptaculous是Grails默认安装的。RichUI插件可以很好的从Ajax库中选择正确的UI。
当查看插件列表时,可以看到对富客户端,如:Flex,OpenLazlo,GWT和ZK的支持。
在GSP文件中有许多有用的以
在控制器中使用def scaffold的作用是指示Grails动态的在运行的时候产生GSP文件。
输入命令grails generate-all Trip会产生控制器和相关的GSP文件
当访问 http://localhost:9090/trip-planner/trip/list时,会先调用TripController来返回Trip的列表,并传递给list.gsp来显示。
下面介绍一些常用的Grails的标签,包括。
是个非常常用的Grails标签。它遍历列表中的每个元素,打开文件/trip/list.gsp 就可以看到如何使用这个标签:
status="i" var="trip">
class="${(i % 2) == 0 ? 'even' : 'odd'}">
id="${trip.id}">${trip.id?.encodeAsHTML()}
${trip.airline?.encodeAsHTML()}${trip.name?.encodeAsHTML()}${trip.city?.encodeAsHTML()}${trip.startDate?.encodeAsHTML()}${trip.endDate?.encodeAsHTML()}Thestatusattribute in the在中,status就是一个简单的计数器。Var属性允许你定义一个当前元素的名字。
另一个Grails 标签是
在list.gsp中还可以看到标签:
class="message">${flash.message}
标签显示的是相关的分页逻辑;把列的标题变成可点击的,用来进行排序。其他的一些标签,如:和指示显示相对应的html元素。
自定义标签库
虽然标准的Grails标签非常有用,但是最终你还是需要自己的标签。
在Grails中创建标签库要比在JSP中创建标签库方便。
在Grails中创建标签库的第一步是输入命令grails create-tag-lib Date。这样就会创建两个文件: grails-app/taglib/DateTagLib.groovy (标签库)和grails-app/test/integration/DateTagLibTests.groovy (测试文件)向文件DateTagLib.groovy中添加以下的代码:
class DateTagLib {
def thisYear =
{
out <<
Calendar.getInstance().get(Calendar.YEAR)
}
}
这样就创建了标签,年的属性直接输出到输出流中。
测试标签库
在文件DateTagLibTests.groovy里添加如下的测试代码:
class DateTagLibTests extends GroovyTestCase {
def dateTagLib
void setUp(){
dateTagLib =
new DateTagLib()
}
void
testThisYear() {
String
expected = Calendar.getInstance().get(Calendar.YEAR)
assertEquals("the years don't match", expected,
dateTagLib.thisYear())
}
}
输入命令grails test-app来进行测试
命令grails test-app除了运行测试用例外,还会生成测试报告。打开文件test/reports/html/index.html可以进行查看。
这样这个标签就测试开发完了。
自定义标签的高级话题
大部分标签可以有body和属性。
class DateTagLib {
def thisYear =
{
out <<
Calendar.getInstance().get(Calendar.YEAR)
}
def copyright =
{ attrs, body ->
out <<
"
out <<
"© ${attrs['startYear']} - ${thisYear()}, ${body()}"
out <<
" All Rights Reserved."
out <<
"
}
}
注意attrs是一个包含标签属性的HashMap。可以通过这个HashMap来得到startYear属性。类似的body是作为一个Closure传递进来的。
默认的自定义的标签都放在g:命名空间下,如果想修改这个行为的话,需要在DateTagLib.groovy 中添加static namespace = 'trip'。这样在GSP中就可以使用以下的方式进行调用:FakeCo
Inc.。
模板
自定义标签库是重用代码的一个好的办法,但是大段的代码的好的重用方式是使用模板。
一个模板就是可以在多个GSP文件中共享的一段GSP代码。在the
grails-app/views/trip目录下创建的文件,只有Trip的视图才能访问。只有在grails-app/views 目录下创建的文件才能全局共享。创建如下的全局模板:
下面来在相应的视图中引入这个模板:
...
为了自定义 scaffolding,需要使用命令grails install-templates。这个命令会向项目添加一个新的目录src/templates。在这个目录下会有三个子目录artifacts、scaffolding和war。
artifacts目录中保存的是生成Controller、DomainClass和TagLib时需要使用的模板。比如:如果想要所有的控制器都扩展一个相同的抽象类。
war目录包含一个web.xml文件。如果需要添加自定义的参数,如:filters 或者 servlets,都可以在这个文件中进行。但你使用grails war命令时,这个文件就会被包含在生成的war文件中。
scaffolding目录中包含的是生成视图时,需要指定的信息。打开 list.gsp 然后添加到文件的底部。