GSP(Groovy Servers Pages)类似于ASP和JSP,页面放置于grails-app/views文件夹下。
render(view: "index")
GSP中有一个概念叫视图模型model,本质上就是个HashMap,用于以键值形式存储变量。如下:
def show() {
[book: Book.get(params.id)] //model,最后一样如此写,等同于return [book: Book.get(params.id)]
}
在页面中使用model的方法:
${book.title}
常用预定义变量:
application - javax.servlet.ServletContext实例
applicationContext - Spring ApplicationContext实例
flash - flash对象
grailsApplication - GrailsApplication实例
out - response writer,输出流
params - params对象,用于获取请求的参数
request - HttpServletRequest实例
response - HttpServletResponse实例
session - HttpSession实例
webRequest - GrailsWebRequest实例
####################
在视图层中引入java类:
<%@ page import="java.awt.*" %>
<%@ page contentType="application/json" %>
表达式的写法(推荐):
<html>
<body>
Hello ${params.name} //获取url中name参数的值
</body>
</html>
####################
<g:set var="now" value="${new Date()}" />
<g:set var="myHTML">
<h2>HTML: ${new Date()}</h2>
</g:set>
<g:set var="bookService" bean="bookService" />
变量作用域scope类型:
page - 当前页(默认)
request - 当前请求
flash - 下次请求
session - session失效前
application - web应用运行中
设定变量作用域scope:
<g:set var="now" value="${new Date()}" scope="request" />
###############
逻辑判断和数组遍历:
<g:if test="${session.role == 'admin'}">
<%-- 管理员功能 --%>
</g:if>
<g:else>
<%-- 基础功能 --%>
</g:else>
<g:each in="${[1,2,3]}" var="num">
<p>数字${num}</p>
</g:each>
<g:set var="num" value="${1}" />
<g:while test="${num < 5 }">
<p>数字${num++}</p>
</g:while>
###############
<g:findAll in="${books}" expr="it.author == 'Stephen King'">
<p>Title: ${it.title}</p>
</g:findAll>
<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>
#############
<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 params="[sort: 'title', order: 'asc', author: currentBook.author]" action="list">Book List</g:link>
#############
form基础:
<g:form name="myForm" url="[controller:'book',action:'list']">...</g:form>
textField - 文本输入框'text'
passwordField - 密码输入框'password'
checkBox - 多选框'checkbox'
radio - 单选框'radio'
hiddenField - 隐藏字段'hidden'
select - 选择框
<g:textField name="myField" value="${myValue}" />
#############
Static Resource: ${createLinkTo(dir: "images", file: "logo.jpg")}
<img src="${createLinkTo(dir: 'images', file: 'logo.jpg')}" />
<img src="<g:createLinkTo dir="images" file="logo.jpg" />" />
def imageLocation = createLinkTo(dir:"images", file:"logo.jpg").toString()
def imageLocation = g.createLinkTo(dir:"images", file:"logo.jpg").toString()
#############
可以使用模板Templates来提高视图View的可重用性,视图与视图模板的区别在于,模板的首字符为下划线,即以下划线开头的视图即为模板,举个例子:
grails-app/views/book/_bookTemplate.gsp
<div class="book" id="${book?.id}">
<div>Title: ${book?.title}</div>
<div>Author: ${book?.author?.name}</div>
</div>
<g:render template="bookTemplate" model="[book: myBook]" />
<g:render template="bookTemplate" var="book" collection="${bookList}" />
共享模板,即横跨views下文件夹共享模板:
grails-app/views/shared/_mySharedTemplate.gsp
<g:render template="/shared/mySharedTemplate" />
<g:render template="/book/bookTemplate" model="[book: myBook]" />
##################
由于模板使用频繁,为使模板的使用变得容易且简洁,可使用特定的命名空间tmpl
<g:render template="bookTemplate" model="[book:myBook]" />
<tmpl:bookTemplate book="${myBook}" />
<tmpl:bookTemplate book="${myBook}" />
在控制器及标签库使用模板:
def bookData() {
def b = Book.get(params.id)
render(template:"bookTemplate", model:[book:b])
}
def bookData() {
def b = Book.get(params.id)
String content = g.render(template:"bookTemplate", model:[book:b])
render content
}
##################
Grails使用Sitemesh来支持视图的布局。布局位于grails-app/views/layouts文件夹下,举个例子:
<html>
<head>
<title><g:layoutTitle default="An example decorator" /></title>
<g:layoutHead />
</head>
<body onload="${pageProperty(name:'body.onload')}">
<div class="menu"><!--my common menu goes here--></div>
<div class="body">
<g:layoutBody />
</div>
</body>
</html>
layoutTitle - 代表子页面标题<title>...</title>
layoutHead - 代表子页面头部<head>...</head>
layoutBody - 代表子页面内容<head>...</head>
注:子页面也叫被装饰页面,被模板装饰。
模板的引用,<meta name="layout" content="main" />,即使用main模板,举个例子:
子页面(被装饰页面):
<html>
<head>
<title>子标题</title>
<meta name="layout" content="main" />
</head>
<body onload="alert('hello');">
子内容
</body>
</html>
附:main模板
<html>
<head>
<title>
<g:layoutTitle default="模板标题" />
</title>
<g:layoutHead />
</head>
<body onload="${pageProperty(name:'body.onload')}">
<div class="menu">模板菜单</div>
<div class="body">
<g:layoutBody />
</div>
</body>
</html>
最终返回结果:
<html>
<head>
<title>子标题</title>
</head>
<body onload="alert('hello');">
<div class="menu">模板菜单</div>
<div class="body">
子内容
</div>
</body>
</html>
题外话,如果子页面没有“子标题”时,就会使用模板标题“模板标题”
为控制器指定模板layout:
class BookController {
static layout = 'customer'
def list() { … }
}
设置默认模板,位置grails-app/conf/application.groovy:
grails.sitemesh.default.layout = 'myLayoutName' //grails-app/views/layouts/myLayoutName.gsp
本文暂时没有评论,来添加一个吧(●'◡'●)