gsp
GSP存在于Grails的grails-app/views目录中,他们通常会自动渲染(通过规约),或者像这样通过render方法:
render(view:"index")
一个GPS通常拥有一个"model",它是变量集被用于视图渲染。通过一个控制器model被传递到GSP视图。例如,考虑下列控制器的操作:
def show = {
[book: Book.get(params.id)]
}
这个操作将查找一个Book 实体,并创建一个包含关键字为book的model,这个关键字可在随后的GSP视图中应用
<%=book.title%>
<g:findAll in="${books}" expr="it.author == 'Stephen King'">
<p>Title: ${it.title}</p>
</g:findAll>
- 使用gsp简单语法
<g:example attr="${new Date()}" attr2="[one:'one', two:'two']">
Hello world
</g:example>
变量和作用域作用域
变量可以在GSP中使用set标签来定义:
<g:set var="now" value="${new Date()}" />
<g:set var="myHTML">
Some re-usable code on: ${new Date()}
</g:set>
变量同样可以被放置于下列的范围内:
- page - 当前页面范围 (默认)
- request - 当前请求范围
- flash - flash作用域,因此它可以在下一次请求中有效
- session - 用户session范围
- application - 全局范围.
<g:set var="now" value="${new Date()}" scope="request" />
逻辑和迭代
- GSP同样支持迭代逻辑标签,逻辑上通过使用if, else 和 elseif来支持典型的分支情形。
<g:if test="${session.role == 'admin'}">
<%-- show administrative functions --%>
</g:if>
<g:else>
<%-- show basic functions --%>
</g:else>
- GSP用each和while 标签来处理迭代:
<g:each in="${[1,2,3]}" var="num">
<p>Number ${num}</p>
</g:each>
<g:set var="num" value="${1}" />
<g:while test="${num < 5 }">
<p>Number ${num++}</p>
</g:while>
搜索和过滤
- 假如你拥有对象集合,你经常需要使用一些方法来排序和过滤他们。GSP支持findAll 和 grep来做这些工作。
<g:findAll in="${books}" expr="it.author == 'Stephen King'">
<p>Title: ${it.title}</p>
</g:findAll>
- expr属性包含了一个Groovy表达式,它可以被当作一个过滤器来使用。谈到过滤器,grep标签通过类来完成与过滤器类似的工作:
<g:grep in="${books}" filter="NonFictionBooks.class">
<p>Title: ${it.title}</p>
</g:grep>
- 或者使用一个正则表达式:
<g:grep in="${books.title}" filter="~/.*?Groovy.*?/">
<p>Title: ${it}</p>
</g:grep>
链接和资源
GSP还拥有特有的标签来帮助你管理连接到控制器和操作.link标签允许你指定控制器和操作配对的名字,并基于URL映射来自动完成连接。即使你去改变!一些 link的示例如下:
<g:link action="show" id="1">Book 1</g:link>
<g:link action="show" id="${currentBook.id}">${currentBook.name}</g:link>
<g:link controller="book">Book Home</g:link>
<g:link controller="book" action="list">Book List</g:link>
<g:link url="[action:'list',controller:'book']">Book List</g:link>
<g:link action="list" params="[sort:'title',order:'asc',author:currentBook.author]">
Book List
</g:link
- createLinkTo的用法
g:createLinkTo dir="css" file="main.css" /> == /shop/css/main.css
<g:createLinkTo dir="css" file="main.css" absolute="true"/> == http://portal.mygreatsite.com/css/main.css
<g:createLinkTo dir="css" file="main.css" base="http://admin.mygreatsite.com"/> == http://admin.mygreatsite.com/css/main.css
<link type="text/css" href="${createLinkTo(dir:'css',file:'main.css')}" />
表单和字段
表单基础
- GSP支持许多不同标签来帮助处理HTML表单和字段,最基础的是form标签,form标签是一个控制器/操作所理解的正规的HTML表单标签版本。 url属性允许你指定映射到哪个控制器和操作:
<g:form name="myForm" url="[controller:'book',action:'list']">...</g:form>
我们创建个名为myForm的表单,它被提交到BookController的list操作。除此之外,适用于所有不同的HTML属性。
表单字段
同构造简单的表单一样,GSP支持如下不同字段类型的定制:
- textField - 'text'类型输入字段
- checkBox - 'checkbox'类型输入字段
- radio - 'radio'类型输入字段
- hiddenField - 'hidden'类型输入字段
- select - 处理 HTML 选择框
上面的每一个都允许GSP表达式作为值:
<g:textField name="myField" value="${myValue}" />
GSP同样包含上面标签的扩张助手版本,比如radioGroup (创建一组radio 标签), localeSelect, currencySelect 和timeZoneSelect (选择各自的地区区域, 货币 和时间区域).
多样的提交按钮
- 处理多样的提交按钮这样由来已久的问题,同样可以通过Grails的actionSubmit标签优雅的处理。它就像一个正规提交,但是,允许你指定一个可选的操作来提交。
<g:actionSubmit value="Some update label" action="update" />
<g:actionSubmit value="Update" />
<!--'Update' is action, label is 'Some update label'-->
<g:actionSubmit value="Some update label" action="Update" />
<!--label derived from message bundle-->
<g:actionSubmit value="${message(code:'label.update')}" action="Update" />
<g:actionSubmit value="Delete" />
<g:actionSubmit value="DeleteAll" onclick="return confirm('Are you sure???')" />
视图和模板
和视图一样,Grails有模板的概念。模板有利于分隔出你的视图在可维护的块中,并与Layouts结合提供一个高度可重用机制来构建视图
模板基础
Grails使用在一个视图名字前放置一个下划线来标识为一个模板的规约。例如,你可能有个位于grails-app/views/book/_bookTemplate.gsp的模板处理渲染Books :
<div class="book" id="${book?.id}">
<div>Title: ${book?.title}</div>
<div>Author: ${book?.author?.name}</div>
</div>
为了渲染来自grails-app/views/book 视图中的一个模板,你可以使用render标签:
<g:render template="bookTemplate" model="[book:myBook]" />
注意,我们是怎么样使用render标签的model属性来使用传入的一个model(就是对应domain)。假如,你有多个Book实体,你同样可以使用render标签为每个Book渲染模板
<g:render template="bookTemplate" var="book" collection="${bookList}" />
共享模板
在早先的示例中,我们有一个特定于BookController模板,它的视图位于 grails-app/views/book。然而,你可能想横跨你的应用来共享模板。
- 既然这样,你可以把他们放置于grails-app/views视图根目录或者位于这个位置的任何子目录,然后在模板属性在模板名字之前使用一个 /来指明相对模板路径
<g:render template="/shared/mySharedTemplate" />
- 你也可以使用这个技术从任何视图或控制器(Controllers)来引用任何目录下的模板:
<g:render template="/book/bookTemplate" model="[book:myBook]" />
在控制器和标签库中的模板
你同样可以使用控制器render方法渲染模板控制器中,它对Ajax引用很有用。
def show = {
de b = Book.get(params.id)
render(template:"bookTemplate", model:[book:b])
}
在控制器中的render方法最普通的行为是直接写入响应。假如,你需要获得模板作为一个String的结果作为替代,你可以使用render标签:
def show = {
de b = Book.get(params.id)
String content = g.render(template:"bookTemplate", model:[book:b])
render content
}