posts - 2, comments - 3, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2009年12月29日

视图存储在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文件中有许多有用的以<g:开头的标签。GSP文件就是Html和Grails标签的混合体。

在控制器中使用def scaffold 的作用是指示Grails动态的在运行的时候产生GSP文件。

输入命令 grails generate-all Trip会产生控制器和相关的GSP文件

当访问 http://localhost:9090/trip-planner/trip/list时,会先调用TripController来返回Trip的列表,并传递给list.gsp来显示。

下面介绍一些常用的Grails的标签,包括<g:each>

<g:each>是个非常常用的Grails标签。它遍历列表中的每个元素,打开文件/trip/list.gsp 就可以看到如何使用这个标签:

<g:each in="${tripList}" status="i" var="trip">

 <tr class="${(i % 2) == 0 ? 'even' : 'odd'}">

    <td><link action="show" id="${trip.id}">${trip.id?.encodeAsHTML()}</g:link></td>

    <td>${trip.airline?.encodeAsHTML()}</td>

    <td>${trip.name?.encodeAsHTML()}</td>

    <td>${trip.city?.encodeAsHTML()}</td>

    <td>${trip.startDate?.encodeAsHTML()}</td>

    <td>${trip.endDate?.encodeAsHTML()}</td>

 </tr>

</g:each>

The status attribute in the<g:each>中,status就是一个简单的计数器。Var属性允许你定义一个当前元素的名字。

另一个Grails 标签是 <g:link>,它建立一个HTML的<a href>连接。<g:createLink>标签会创建一个真正的URL字符串。在list.gsp上部,你可以看到另一个和连接相关的标签<g:createLinkTo>,这个标签接受一个dirfile属性:

<div class="nav">

 <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>

 <span class="menuButton"><link class="create" action="create">New Trip</g:link></span>

</div>

在list.gsp中还可以看到<g:if>标签:

<h1>Trip List</h1>

<if test="${flash.message}">

 <div class="message">${flash.message}</div>

</g:if>

<g:paginate>标签显示的是相关的分页逻辑;<g:sortable>把列的标题变成可点击的,用来进行排序。其他的一些标签,如:<g:form><g:submit>指示显示相对应的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)

 }

}

这样就创建了<g:thisYear>标签,年的属性直接输出到输出流中。

测试标签库

在文件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 << "<div id='copyright'>"

    out << "&copy; ${attrs['startYear']} - ${thisYear()}, ${body()}"

    out << " All Rights Reserved."

    out << "</div>"

 }

}

注意attrs是一个包含标签属性的HashMap。可以通过这个HashMap来得到startYear属性。类似的body是作为一个Closure传递进来的。

默认的自定义的标签都放在g:命名空间下,如果想修改这个行为的话,需要在DateTagLib.groovy 中添加static namespace = 'trip'。这样在GSP中就可以使用以下的方式进行调用:<trip:copyright startYear="2002">FakeCo Inc.</trip:copyright>

模板

自定义标签库是重用代码的一个好的办法,但是大段的代码的好的重用方式是使用模板。

一个模板就是可以在多个GSP文件中共享的一段GSP代码。在the grails-app/views/trip 目录下创建的文件,只有Trip的视图才能访问。只有在grails-app/views 目录下创建的文件才能全局共享。创建如下的全局模板:

<div id="footer">

 <g:copyright startYear='2002'>FakeCo, Inc.</g:copyright>

 <div id="powered-by">

    <img src="${createLinkTo(dir:'images', file:'grails-powered.jpg')}" />

 </div>

</div>

下面来在相应的视图中引入这个模板:

               

<html><body>

...

<g:render template="/footer" />

</body></html>

自定义scaffolding

为了自定义 scaffolding,需要使用命令grails install-templates。这个命令会向项目添加一个新的目录src/templates。在这个目录下会有三个子目录artifacts、scaffolding和war。

artifacts 目录中保存的是生成ControllerDomainClassTagLib时需要使用的模板。比如:如果想要所有的控制器都扩展一个相同的抽象类。

war 目录包含一个web.xml文件。如果需要添加自定义的参数,如:filters 或者 servlets,都可以在这个文件中进行。但你使用grails war命令时,这个文件就会被包含在生成的war文件中。

scaffolding 目录中包含的是生成视图时,需要指定的信息。打开 list.gsp 然后添加 <g:render template="/footer" />到文件的底部。

posted @ 2009-12-29 14:21 杨晓晨 阅读(5712) | 评论 (1)编辑 收藏