现在的位置: 首页 > 综合 > 正文

Groovy轻松入门——Grails实战之Ajax篇

2019年09月24日 ⁄ 综合 ⁄ 共 12904字 ⁄ 字号 评论关闭

Ajax虽是“旧酒装新瓶”,但其威力着实不小。近两年来可谓红透半边天,它之所以能为大众接受,其中一个很大的原因就是提高了用户浏览体验,能更逼真的模拟出GUI界面。好了,Ajax的益处就说到这里,下面让我们看下Grails是如何帮助我们方便地应用Ajax的:

如果您对下面说设计的内容有点不解,那么您可以先看一下 Groovy轻松入门——Grails实战基础篇,然后开始我们的Ajax之旅。

1, 在命令行中输入:“grails create-app AjaxDemo”(注意:不带引号“”)创建一个Grails project,我将它命名为AjaxDemo:

D:/Temp/grails_apps>grails create-app AjaxDemo

Welcome to Grails 0.5 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:/D/MY_DEV/grails-0.5

Base Directory: D:/Temp/grails_apps
Environment set to production
Note: No plugin scripts found
Running script D:/D/MY_DEV/grails-0.5/scripts/CreateApp.groovy
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/src
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/src/java
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/src/groovy
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/src/test
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/controllers
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/jobs
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/services
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/domain
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/taglib
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/utils
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/views
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/views/layouts
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/i18n
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-app/conf
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/grails-tests
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/scripts
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/js
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/css
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/images
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/classes
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/META-INF
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/lib
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/spring
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/hibernate
[propertyfile] Creating new property file: D:/Temp/grails_apps/AjaxDemo/application.properties
     [copy] Copying 2 files to D:/Temp/grails_apps/AjaxDemo
     [copy] Copying 2 files to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF
     [copy] Copying 5 files to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/tld
     [copy] Copying 119 files to D:/Temp/grails_apps/AjaxDemo/web-app
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/grails-app/conf
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/grails-app/conf
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/grails-app/conf
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/grails-app/conf
     [copy] Copying 13 files to D:/Temp/grails_apps/AjaxDemo/grails-app
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/plugins/core/grails-app/taglib
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/plugins/core/grails-app/utils
     [copy] Copying 7 files to D:/Temp/grails_apps/AjaxDemo/plugins/core/grails-app/taglib
     [copy] Copying 4 files to D:/Temp/grails_apps/AjaxDemo/plugins/core/grails-app/utils
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/spring
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo
[propertyfile] Updating property file: D:/Temp/grails_apps/AjaxDemo/application.properties
Created Grails Application at D:/Temp/grails_apps/AjaxDemo
D:/Temp/grails_apps>


2,“cd AjaxDemo”,进入AjaxDemo目录,输入“grails create-domain-class User”,创建一个域类User:

D:/Temp/grails_apps/AjaxDemo>grails create-domain-class User

Welcome to Grails 0.5 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:/D/MY_DEV/grails-0.5

Base Directory: D:/Temp/grails_apps/AjaxDemo
Environment set to production
Running script D:/D/MY_DEV/grails-0.5/scripts/CreateDomainClass.groovy
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/grails-app/domain
Created  for User
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/grails-tests
Created Tests for User
D:/Temp/grails_apps/AjaxDemo>

3,“grails generate-all User”,生成scaffolding code(如:list.gsp等):

D:/Temp/grails_apps/AjaxDemo>grails generate-all User

Welcome to Grails 0.5 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:/D/MY_DEV/grails-0.5

Base Directory: D:/Temp/grails_apps/AjaxDemo
Environment set to production
Running script D:/D/MY_DEV/grails-0.5/scripts/GenerateAll.groovy
Compiling sources 
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/lib
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/spring
     [copy] Copying 34 files to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/lib
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/grails-app/i18n
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/grails-app/views
     [copy] Copying 2 files to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/grails-app/views
    [mkdir] Created dir: D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/templates/scaffolding
     [copy] Copying 5 files to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/templates/scaffolding
[native2ascii] Converting 7 files from D:/Temp/grails_apps/AjaxDemo/grails-app/i18n to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/grails-app/i1
8n
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/spring
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/classes
     [copy] Copying 1 file to D:/Temp/grails_apps/AjaxDemo/web-app/WEB-INF/classes
Generating views for domain class [User]
Generating list view for domain class [User]
list view generated at D:/Temp/grails_apps/AjaxDemo/./grails-app/views/user/list.gsp
Generating show view for domain class [User]
Show view generated at D:/Temp/grails_apps/AjaxDemo/./grails-app/views/user/show.gsp
Generating edit view for domain class [User]
Edit view generated at D:/Temp/grails_apps/AjaxDemo/./grails-app/views/user/edit.gsp
Generating create view for domain class [User]
Create view generated at D:/Temp/grails_apps/AjaxDemo/./grails-app/views/user/create.gsp
Generating controller for domain class [User]
Controller generated at ./grails-app/controllers/UserController.groovy
D:/Temp/grails_apps/AjaxDemo>

4,修改AjaxDemo/grails-app/controllers/UserController.groovy的内容为:

            
class  UserController {
    def index 
=  { redirect(action:list,params:params) }

     //  the delete, save and update actions only
    
//  accept POST requests
    def allowedMethods  =  [delete: ' POST ' ,
                          save:
' POST ' ,
                          update:
' POST ' ]

    def list  =  {
        
if ( ! params.max)params.max  =   10
        [ userList: User.list( params ) ]
    }

    def show  =  {
        [ user : User.get( params.id ) ]
    }

    def delete  =  {
        def user 
=  User.get( params.id )
        
if (user) {
            user.delete()
            flash.message 
=   " User ${params.id} deleted. "
            redirect(action:list)
        }
        
else  {
            flash.message 
=   " User not found with id ${params.id} "
            redirect(action:list)
        }
    }

    def edit  =  {
        def user 
=  User.get( params.id )

         if ( ! user) {
                flash.message 
=   " User not found with id ${params.id} "
                redirect(action:list)
        }
        
else  {
            
return  [ user : user ]
        }
    }

    def update  =  {
        def user 
=  User.get( params.id )
        
if (user) {
             user.properties 
=  params
            
if (user.save()) {
                redirect(action:show,id:user.id)
            }
            
else  {
                render(view:
' edit ' ,model:[user:user])
            }
        }
        
else  {
            flash.message 
=   " User not found with id ${params.id} "
            redirect(action:edit,id:params.id)
        }
    }

    def create  =  {
        def user 
=   new  User()
        user.properties 
=  params
        
return  [ ' user ' :user]
    }

    def save  =  {
        def user 
=   new  User()
        user.properties 
=  params
        
if (user.save()) {
            redirect(action:show,id:user.id)
        }
        
else  {
            render(view:
' create ' ,model:[user:user])
        }
    }

     //  自己添加的Closure ajax定义
    def ajax  =  {}
    
    
//  自己添加的Closure sayHello定义
    def sayHello  =  {
        render 
" [${new Date()}] Hello, ${params.name} "
    }

}

添加sayHello闭包的目的很明显,因为客户端需要调用。那为什么还要添加ajax这个闭包呢?其实添加 ajax 这个闭包的目的是使http://localhost:8080/AjaxDemo/user/ ajax 这个请求合法化,否则会发生404错误,找不到页面:

HTTP ERROR: 404

Not Found

RequestURI=/AjaxDemo/user/ajax

Powered by Jetty://

所以被客户端请求的 每个 gsp页面,都需要在相应的Controller中添加以gsp文件名为变量名的Closure,如上面的ajax.gsp和ajax = {}所示,其中Closure中可以添加相关代码,我们这里仅仅是做Ajax的演示,所以就不需要代码

5,在AjaxDemo/grails-app/views/user目录下,新建ajax.gsp,用来演示remoteLink的用法,内容为:

< g:javascript  library ="prototype"   />

< div  id ="hello" > Content will be displayed here </ div >

< g:remoteLink  action ="sayHello"  params ="[name:'BlueSUN']"  update ="hello" >Say Hello </ g:remoteLink >

params表示要传递的参数,而update表示返回结果显示的地方,注意update="hello"中的hello对应于div的id,表示结果将显示于div所在处。

点击链接后的界面:

[Fri May 11 17:46:47 CST 2007] Hello, BlueSUN

Say Hello

6,修改AjaxDemo/grails-app/views/user/ ajax.gsp,演示formRemote的用法,内容为:

<g:javascript library="prototype" />

<div id="hello">Content will be displayed here</div>
<div id="error"></div>

<g:remoteLink action="sayHello" params="[name:'BlueSUN']" update="hello">Say Hello</g:remoteLink>

<hr />

<g:formRemote name="test" url="[controller:'user',action:'sayHello']" update="[success:'hello',failure:'error']">
    
<input type="text" name="name" value="BlueSUN" />
    
<input type="submit" value="Say Hello" />
</g:formRemote >

原本用params传递的参数,现在可以以form的形式传递了,将想传递的内容输入name的textfield中即可。

默认值我设为BlueSUN,现在我将值改为terry,点击Say Hello按钮,结果如下:

[Fri May 11 18:16:17 CST 2007] Hello, terry

Say Hello




7,修改AjaxDemo/grails-app/views/user/
ajax.gsp和AjaxDemo/grails-app/controllers/UserController.groovy,演示remoteField的用法:
ajax.gsp:

<g:javascript library="prototype" />

<div id="hello">Content will be displayed here</div>
<div id="error"></div>

<g:remoteLink action="sayHello" params="[name:'BlueSUN']" update="hello">Say Hello</g:remoteLink>

<hr />

<g:formRemote name="test" url="[controller:'user',action:'sayHello']" update="[success:'hello',failure:'error']">
    
<input type="text" name="name" value="BlueSUN" />
    
<input type="submit" value="Say Hello" />
</g:formRemote >

<hr />

<g:remoteField action="sayHello2" update="hello"  name="name" value="" />

UserController.groovy:

            
class UserController {
    def index 
= { redirect(action:list,params:params) }

    // the delete, save and update actions only
    
// accept POST requests
    def allowedMethods = [delete:'POST',
                          save:
'POST',
                          update:
'POST']

    def list = {
        
if(!params.max)params.max = 10
        [ userList: User.list( params ) ]
    }

    def show = {
        [ user : User.get( params.id ) ]
    }

    def delete = {
        def user 
= User.get( params.id )
        
if(user) {
            user.delete()
            flash.message 
= "User ${params.id} deleted."
            redirect(action:list)
        }
        
else {
            flash.message 
= "User not found with id ${params.id}"
            redirect(action:list)
        }
    }

    def edit = {
        def user 
= User.get( params.id )

        if(!user) {
                flash.message 
= "User not found with id ${params.id}"
                redirect(action:list)
        }
        
else {
            
return [ user : user ]
        }
    }

    def update = {
        def user 
= User.get( params.id )
        
if(user) {
             user.properties 
= params
            
if(user.save()) {
                redirect(action:show,id:user.id)
            }
            
else {
                render(view:
'edit',model:[user:user])
            }
        }
        
else {
            flash.message 
= "User not found with id ${params.id}"
            redirect(action:edit,id:params.id)
        }
    }

    def create = {
        def user 
= new User()
        user.properties 
= params
        
return ['user':user]
    }

    def save = {
        def user 
= new User()
        user.properties 
= params
        
if(user.save()) {
            redirect(action:show,id:user.id)
        }
        
else {
            render(view:
'create',model:[user:user])
        }
    }

    // 自己添加的Closure ajax定义
    def ajax = {}
    
    
// 自己添加的Closure sayHello定义
    def sayHello = {
        render 
"[${new Date()}] Hello, ${params.name}"
    }
    
    
// 自己添加的Closure sayHello2定义
    def sayHello2 = {
        render 
"[${new Date()}] Hello, ${params.value}"
    }

}

由于 用remoteField传递过来的参数名为value,又为了保留以前的演示,所以再定义一个sayHello2闭包,注意是params.value而非params.name

抱歉!评论已关闭.