编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Grails指南26Web层控制器基础(web grid)

wxchong 2024-10-05 02:12:15 开源技术 9 ℃ 0 评论

控制器Controller主要用于处理请求以及响应请求,响应请求的方式可以是直接响应(关键词render)或者间接响应(返回视图View)。创建控制器的方法其实很简单,只需在grails-app/controllers下创建一个以Controller结尾的groovy类即可。

URL Mapping,建立URL与控制器Controller的操作Action,或URL与视图View之间的关联。

创建控制器的命令:

grails create-controller book

命令执行后将会创建一个控制器,位置在grails-app/controllers/lvchanglong/BookController.groovy

package lvchanglong //包名lvchanglong

class BookController {

def index() { }

}

如果没指定,默认包名将是应用名称(grails create-app lvchanglong)

创建方法:

class BookController {

def list() {

// 写控制器的逻辑

// 创建一个HashMap,名称可以是model,model的值可用在视图层中,简单理解,model就是视图层需要展示的数据。

return model

}

}

控制器中默认方法。如访问/book,即控制器是BookController,方法为默认方法。默认方法的选取规则如下:

1.如果只有一个方法Action,则此方法为默认方法。

2.如果定义了index方法,则此方法为默认方法。

3.设置defaultAction指定默认方法,代码如下:

static defaultAction = "list"

控制器和作用域。作用域的本质就是Hash对象,允许你存储变量。以下是在控制器Controller中可用的作用域:

servletContext - 也被称为application作用域,允许你在整个web应用程序中共享状态(变量),servletContext是类ServletContext的一个实例。

session - 关联存储某个给定用户的状态(变量),通常使用Cookie把一个session同一位客户关联起来。session对象是类HttpSession的一个实例。

request - request只负责当前请求对象的存储工作。request对象是类HttpServletRequest的一个实例。

params - 用于存储请求request的参数信息

flash - 只用于临时存储用于本次请求的变量,即只存储本次请求到下个请求间的变量

作用域的使用:

class BookController {

def find() { //不推荐使用

def findBy = params["findBy"]

def appContext = request["foo"]

def loggedUser = session["logged_user"]

}

}

推荐用法,原因这样写更简洁、更清晰:

class BookController {

def find() { //以下方法推荐使用

def findBy = params.findBy

def appContext = request.foo

def loggedUser = session.logged_user

}

}

flash的使用:

def delete() {

def b = Book.get(params.id)

if (!b) {

flash.message = "用户不存在:${params.id}"

redirect(action:list)

}

... // 余下的代码

}

#####################

prototype、session、singleton

grails:

controllers:

defaultScope: singleton

#####################

返回视图模型Model,Model本质就是Map,通常在视图渲染时使用,map中的键key,即变量名,常用于视图中变量值的获取

def show() {

[book: Book.get(params.id)]

}

更高级的用法,Spring的ModelAndView类的实例的使用:

import org.springframework.web.servlet.ModelAndView

def index() {

// get some books just for the index page, perhaps your favorites

def favoriteBooks = ... //Book.list()

// forward to the list view to show them

return new ModelAndView("/book/list", [ bookList : favoriteBooks ])

}

视图的选择:

class BookController {//去除Controller,即Book,首字母小写,即book

def show() {

[book: Book.get(params.id)]

}

}

视图位置:grails-app/views/book/show.gsp //去除.gsp,即show

#####################

关于grails的一个约定:

控制器的简称,如BookController的book,与views下的文件夹对应同名;控制器中的方法名,与去除后缀的页面名称对应同名。

#####################

当需指定不同视图时,可使用render:

def show() {

def map = [book: Book.get(params.id)]

render(view: "display", model: map) //对应着视图:grails-app/views/book/display.gsp

}

def show() {

def map = [book: Book.get(params.id)]

render(view: "/shared/display", model: map) //对应着视图:grails-app/views/shared/display.gsp

}

#####################

命名空间的使用,设计不同版本的页面:

class ReportingController {

static namespace = 'business'

def humanResources() {

// This will render grails-app/views/business/reporting/humanResources.gsp

// if it exists.

// If grails-app/views/business/reporting/humanResources.gsp does not

// exist the fallback will be grails-app/views/reporting/humanResources.gsp.

// The namespaced GSP will take precedence over the non-namespaced GSP.

[numberOfEmployees: 9]

}

def accountsReceivable() {

// This will render grails-app/views/business/reporting/accounting.gsp

// if it exists.

// If grails-app/views/business/reporting/accounting.gsp does not

// exist the fallback will be grails-app/views/reporting/accounting.gsp.

// The namespaced GSP will take precedence over the non-namespaced GSP.

render view: 'numberCrunch', model: [numberOfEmployees: 13]

}

}

####################

Ajax的响应工作,通常是render负责:

render "Hello World!" //返回文本

render { //返回标签

for (b in books) {

div(id: b.id, b.title)

}

}

render(view: 'show') //返回视图

render(template: 'book_template', collection: Book.list()) //返回视图模板

render(text: "<xml>some xml</xml>", contentType: "text/xml", encoding: "UTF-8")// 返回指定了编码方式encoding及文本类型content type的文本

#######################

import groovy.xml.MarkupBuilder

...

def login() {

def writer = new StringWriter()

def builder = new MarkupBuilder(writer)

builder.html {

head {

title 'Log in'

}

body {

h1 'Hello'

builder.form { //注意写法

}

}

}

def html = writer.toString()

render html

}

#######################

重定向与链接

class OverviewController {

def find() {

if (!session.user)

redirect(action: 'login')

return

}

}

}

redirect方法内部使用的是HttpServletResponse对象的sendRedirect方法,redirect方法使用方式如下:

redirect(controller: 'home', action: 'index')

redirect(uri: "/login.html")

redirect(url: "http://grails.org")

redirect Book.first()

redirect(action: 'myaction', params: [myparam: "myvalue"])

redirect(action: "next", params: params)

redirect(controller: "test", action: "show", fragment: "profile")//http://localhost:8080/lvchanglong/test/show#profile

######################

链接

class ExampleChainController {

def first() {

chain(action: second, model: [one: 1])

}

def second () {

chain(action: third, model: [two: 2])

}

def third() {

[three: 3])

}

}

model为[one: 1, two: 2, three: 3]

在页面中使用model:

${one}-${two}-${three}

附加:

chain(action: "action1", model: [one: 1], params: [myparam: "param1"])

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表