Grails框架之GSP标签

2017-01-19 17:32

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
}