NEO

蜀道难,难于上青天!

导航

20130517-Grails In Action-5、控制应用程序流(01小节)

Posted on 2013-05-18 19:27  页面载入出错  阅读(382)  评论(0)    收藏  举报

内容简介

  • 控制controller、model、view之间的作用
  • 实现自定义url和永久链接
  • 使用过滤器
  • 使用service让业务逻辑和页面跳转分离
  • 数据绑定和错误处理
  • 使用command对象,处理比较棘手的验证
  • 上传和读取照片文件

一、控制controller、model、view之间的作用

controller的要领

http://ip:端口/应用程序名/controller/action/参数id

1、显示用户所有发帖

在controllers/com.grailsinacition.PostController/建立一个timeline action

1     def timeline = {
2         def user = User.findByUserId(params.id)
3         [ user : user ]
4     }

我们需要访问这个action时的地址就是http://localhost:8080/hubbub/post/timeline/userid

增加一个视图,将action返回的内容显示到页面上,视图的路径为post/timeline

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <title>Timeline for ${user.profile.fullName}
 5 </title>
 6 <meta name="layout" content="main" />
 7 </head>
 8 
 9 <body>
10     <h1>
11         Timeline for ${user.profile.fullName}
12     </h1>
13     
14     <div class="allPosts">
15         <g:each in="${user.posts}" var="post">
16             <div class="postEntry">
17                 <div class="postText">${post.content}</div>
18                 <div class="postDate">${post.dateCreated}</div>
19             </div>
20         </g:each>
21     </div>
22 </body>
23 </html>

如果不想让action和view使用同一个页面来渲染,action的返回值可以这样表示

render(view: "user_timeline", model: [ user: user ])

那么访问的页面就应该是post/user_timeline/userid

2、增加新帖

一般增加新帖和显示历史帖都放在一个界面显示,所以增加新帖只需要在显示帖的页面增加一个form

修改post/timeline

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <title>Timeline for ${user.profile.fullName}
 5 </title>
 6 <meta name="layout" content="main" />
 7 </head>
 8 
 9 <body>
10     <h1>
11         Timeline for ${user.profile.fullName}
12     </h1>
13     
14     <div id="newPost">
15         <h3>What is ${user.profile.fullName} hacking on right now?</h3>
16         <p>
17             <g:form action="addPost" id="${params.id}">
18                 <g:textArea id='postContent' name="content" rows="3" cols="50"/><br/>
19                 <g:submitButton name="post" value="Post"/>
20             </g:form>
21         </p>
22     </div>
23 
24     <div class="allPosts">
25         <g:each in="${user.posts}" var="post">
26             <div class="postEntry">
27                 <div class="postText">${post.content}</div>
28                 <div class="postDate">${post.dateCreated}</div>
29             </div>
30         </g:each>
31     </div>
32 </body>
33 </html>

form提交给addPost,所以在PostController中增加一个addPost闭包处理,addPost负责插入表单数据,并返回页面

 1     def addPost = {
 2         def user = User.findByUserId(params.id)
 3         if (user) {
 4             def post = new Post(params)
 5             user.addToPosts(post)
 6             if (user.save()) {
 7                 flash.message = "Successfully created Post"
 8             } else {
 9                 user.discard()
10                 flash.message = "Invalid or empty post"
11             }
12         } else {
13             flash.message = "Invalid User Id"
14         }
15         redirect(action: 'timeline', id: params.id)
16     }

这个闭包里有一些提示消息(flash.message),为了让这些错误提示消息能正常的反馈到页面,现在修改一下post/timeline

1 ......
2     </h1>
3     
4     <g:if test="${flash.message}">
5         <div class="flash">${flash.message}</div>
6     </g:if>
7     
8     <div id="newPost">
9 ......

 请求的作用域

作用域 范围
page 当前页面范围 (默认)
request 当前请求范围
flash 它可以在下一次请求中有效
session 用户session范围
application 全局范围

当我们在uri上直接访问http://localhost:8080/hubbub/post/timeline时,会默认请求index,我们的index是没有参数的,所以系统会出现找不到参数的错误,所以这里给一个默认的id供默认请求使用

1     def index = {
2         if (!params.id) {
3             params.id = "admin"
4             redirect(action: 'timeline', params: params)
5         }
6     }

另外一种默认页面的处理方式是

def defaultAction = 'timeline'

这样,只要访问http://localhost:8080/hubbub/post,页面也会跳转到timeline,这就是重定向的一种方法,关于重定向还有下面几种方法

1、直接跳转到指定action

redirect(action:'timeline')

2、直接跳转到指定的controller/action/params

redirect(controller: 'post', action:'timeline', id: newUser.userId)

3、复杂参数跳转

redirect(controller: 'post', action:'timeline',params: [fullName: newUser.profile.fullName,email: newUser.profile.email ])

4、不带参数的跳转,有两种方式(controler/action、uri)

redirect(controller: 'post', action:'timeline')
redirect(uri: '/post/timeline')

5、还可以跳转到外部连接

redirect(url: 'http://www.google.com?q=hubbub')