如果您對下面說設計的內容有點不解,那么您可以先看一下 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>
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>
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>
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錯誤,找不到頁面: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} "
????}
}
HTTP ERROR: 404
Not Found
RequestURI=/AjaxDemo/user/ajax
所以被客戶端請求的 每個 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所在處。
< div? id ="hello" > Content?will?be?displayed?here </ div >
< g:remoteLink? action ="sayHello" ?params ="[name:'BlueSUN']" ?update ="hello" >Say Hello </ g:remoteLink >
點擊鏈接后的界面:
[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中即可。<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?>
默認值我設為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=""?/>
<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.nameclass?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}"
????}
}
輸入“BlueSUN” ,請注意輸入時頁面的相應更新效果,結果界面:
輸入到一半,即輸入“Blue”
[Fri May 11 18:34:03 CST 2007] Hello, Blue
Say Hello
緊接著輸入“SUN”
[Fri May 11 18:32:42 CST 2007] Hello,
BlueSUN
Say Hello
8,修改AjaxDemo\grails-app\views\user\ ajax.gsp,演示remoteFunction的用法,內容為:
<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=""?/>
<hr?/>
<button?onClick="${remoteFunction(action:'sayHello',update:[success:'hello',?failure:'error'],?params:'\'name=\'?+?\'BlueSUN\'')}">Say?Hello</button>
<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=""?/>
<hr?/>
<button?onClick="${remoteFunction(action:'sayHello',update:[success:'hello',?failure:'error'],?params:'\'name=\'?+?\'BlueSUN\'')}">Say?Hello</button>
點擊Say Hello按鈕后,結果頁面:
[Fri May 11 18:48:37 CST 2007] Hello,
BlueSUN
Say Hello
9,Grails也可以利用Ajax異步顯示Server端返回的頁面,新建頁面AjaxDemo\grails-app\views\user\result.gsp:
<
html
>
???? < head >
????????? < meta? http-equiv ="Content-Type" ?content ="text/html;?charset=UTF-8" />
????????? < meta? name ="layout" ?content ="main" ? />
????????? < title > Result?Page </ title >
???? </ head >
???? < body >
???????? < div? class ="nav" >
???????????? < span? class ="menuButton" >< a? href ="${createLinkTo(dir:'')}" > Home </ a ></ span >
???????? </ div >
???????? < div? class ="body" >
??????????? < h1 > ${name} </ h1 >
???????? </ div >
???? </ body >
</ html >
???? < head >
????????? < meta? http-equiv ="Content-Type" ?content ="text/html;?charset=UTF-8" />
????????? < meta? name ="layout" ?content ="main" ? />
????????? < title > Result?Page </ title >
???? </ head >
???? < body >
???????? < div? class ="nav" >
???????????? < span? class ="menuButton" >< a? href ="${createLinkTo(dir:'')}" > Home </ a ></ span >
???????? </ div >
???????? < div? class ="body" >
??????????? < h1 > ${name} </ h1 >
???????? </ div >
???? </ body >
</ html >
修改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} "
????}
????
???? // ?自己添加的Closure?sayHello2定義
????def?sayHello2? = ?{
????????render? " [${new?Date()}]?Hello,?${params.value} "
????}
???? // ?自己添加的Closure?displayResultPage定義
????def?displayResultPage? = ?{
????????render(view: ' result ' ,?model:[name:params.name])
????}
}
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} "
????}
???? // ?自己添加的Closure?displayResultPage定義
????def?displayResultPage? = ?{
????????render(view: ' result ' ,?model:[name:params.name])
????}
}
修改AjaxDemo\grails-app\views\user\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 ="" ? />
< hr? />
< button? onClick ="${remoteFunction(action:'sayHello',update:[success:'hello',?failure:'error'],?params:'\'name=\'?+?\'BlueSUN\'')}" > Say?Hello </ button >
< hr? />
< g:formRemote? name ="test" ?url ="[controller:'user',action:'displayResultPage']" ?update ="[success:'hello',failure:'error']" >
???? < input? type ="text" ?name ="name" ?value ="BlueSUN" ? />
???? < input? type ="submit" ?value ="Say?Hello" ? />
</ g:formRemote? >
< 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 ="" ? />
< hr? />
< button? onClick ="${remoteFunction(action:'sayHello',update:[success:'hello',?failure:'error'],?params:'\'name=\'?+?\'BlueSUN\'')}" > Say?Hello </ button >
< hr? />
< g:formRemote? name ="test" ?url ="[controller:'user',action:'displayResultPage']" ?update ="[success:'hello',failure:'error']" >
???? < input? type ="text" ?name ="name" ?value ="BlueSUN" ? />
???? < input? type ="submit" ?value ="Say?Hello" ? />
</ g:formRemote? >
輸入“terry”,點擊Say Hello按鈕,結果頁面(樣式的丟失是因為在ajax.gsp中沒有聲明css,目的是抓重點,拋開一切瑣碎的內容):
最后要提醒大家一點,如果要使用中文,請將中文寫在AjaxDemo\grails-app\i18n\messages_zh_CN.properties中,然后用<g:message code="key" />來顯示。
正如各位所看到的那樣,在Grails中使用Ajax就是那么簡單,此外DWR插件即將出爐,到時利用DWR來開發Ajax應用也將變的十分方便 :)
如果您急需使用DWR,請參考《 Groovy輕松入門——Grails實戰之遺留框架利用篇 》
附:朝花夕拾——Groovy & Grails