Grails WEB层 AJAX

来源:互联网 发布:剑灵龙女身材数据 编辑:程序博客网 时间:2024/05/20 20:45

6.7 Ajax

Ajax代表异步Javascript与XML,它是转向富web应用程序的驱动力. 这些类型的应用程序,通常更适合于像Ruby和Groovy语言所写的敏捷,动态框架,Grails通过它的Ajax标签库提供支持构建Ajax应用程序. 它们完整的列表可以参看标签库参考.

6.7.1 用Prototype实现Ajax

Grails默认装载Prototype 库,但通过Plug-in 系统,可以提供对Dojo,Yahoo UI 和Google Web Toolkit 等其他框架的支持.

这部分涵盖Grails对Prototype的支持。你需要在页面的<head>标签内添加这样一行就可以开始了 :

 

<g:javascript library="prototype" />

这里使用javascript标签自动插入Prototype正确位置的引用。假如你同样需要Scriptaculous ,你可以如下这样做为替换 :

 

<g:javascript library="scriptaculous" />

 

6.7.1.1 远程链接

远程内容可以通过多种方式加载,最常使用的方法是通过 remoteLink 标签。 这个标签允许创建的HTML锚标记执行一个异步请求,并在一个元素中随意设置响应。用这个简单方式创建的远程链接就像这样 :

 

<g:remoteLink action="delete" id="1">Delete Book</g:remoteLink>

上面的连接发送一个异步请求给当前id为1的控制器的delete操作 .

6.7.1.2 内容更新

这真是太棒了,但通常你想提供一些事情发生的反馈信息给用户:

 

def delete = {      def b = Book.get( params.id )      b.delete()      render "Book ${b.id} was deleted"}

GSP代码:

 

<div id="message"></div><g:remoteLink action="delete" id="1" update="message">Delete Book</g:remoteLink>

上面的示例将调用这个操作并设置message div的响应内容为"Book 1 was deleted"。这通过标签上的update属性来完成,它同样可以获取一个map来指出在失败时什么被更新 :

 

<div id="message"></div><div id="error"></div><g:remoteLink action="delete" id="1"              update="[success:'message',failure:'error']">Delete Book</g:remoteLink>

这里,error div在请求失败时被更新.

6.7.1.3 远程表单提交

,一个HTML form也可以异步被提交通过以下两种方式之一。第一个,使用 formRemote 标签,它和remoteLink 标签有类似的属性 :

 

<g:formRemote url="[controller:'book',action:'delete']" update="[success:'message',failure:'error']">       <input type="hidden" name="id" value="1" />       <input type="submit" value="Delete Book!" /></g:formRemote >

或者作为选择可以使用submitToRemote来创建一个提交按钮。它允许一些按钮远程提交而一些不依赖操作 :

 

<form action="delete">       <input type="hidden" name="id" value="1" />       <g:submitToRemote action="delete" update="[success:'message',failure:'error']" /></form>

 

6.7.1.4 Ajax事件

某些事件的发生会调用特定的javascript。所有以"on"开头的事件,在适当的时候允许你反馈信息给用户,或采取其他行为:

 

<g:remoteLink action="show"               id="1"               update="success"               onLoading="showProgress()"               onComplete="hideProgress()">Show Book 1</g:remoteLink>

上述代码将执行"showProgress()"函数来显示一个进度条或者其他适当的展示,其他的事件还包括 :

  • onSuccess - 成功时调用的javascript函数
  • onFailure - 失败时调用的javascript函数
  • on_ERROR_CODE - 处理指定的错误代码时调用的javascript函数 (例如 on404="alert('not found!')")
  • onUninitialized - 一个ajax引擎初始化失败时调用的javascript函数
  • onLoading - 当远程函数加载响应时调用的javascript函数
  • onLoaded - 当远程函数加载完响应时调用的javascript函数
  • onComplete - 当远程函数完成(包括任何更新)时调用的javascript函数

假如你需要引用XmlHttpRequest对象,你可以使用隐式的event参数e获取它 :

 

<g:javascript>   function fireMe(e) {   alert("XmlHttpRequest = " + e)   }}</g:javascript><g:remoteLink action="example"               update="success"               onSuccess="fireMe(e)">Ajax Link</g:remoteLink>

 

6.7.2 用Dojo实现Ajax

Grails把 Dojo 作为一种外部插件来支持Grails的特性。在终端窗口,进入你项目的根目录键入下列命令来安装插件 :

 

grails install-plugin dojo

将下载Dojo最新的支持版本,并安装到你的Grails项目中。完成上面的步骤后,你可以在你页面的顶部添加下列引用:

 

<g:javascript library="dojo" />

现在,所有像remoteLink, formRemote 和 submitToRemote标签都可以和Dojo进行远程处理工作 .

6.7.3 用GWT实现Ajax

Grails同样支持 Google Web Toolkit 特性,插件的全面 文档 可以在Grails wiki中找到 .

6.7.4 服务端的Ajax

虽然Ajax特性X为XML,但通常可以分解成许多不同方式执行Ajax:

  • 内容为中心的 Ajax - 只不过是使用远程调用的HTML结果来更新页面
  • 数据为中心的Ajax - 实际上是发送一个来自于服务器端的XML或JSON,通过编程更新页面
  • 脚本为中心的 Ajax - 服务器端发送的Javascript流在运行中被赋值

在Ajax部分中的更多的示例涵盖了内容为中心的 Ajax在什么地方更新页面,但同样你可能使用数据为中心的Ajax或脚本为中心的 Ajax。这份指南涵盖了不同风格的Ajax .

 

内容为中心的Ajax

作为概括,内容为中心的 Ajax涉及从服务器端发送一些HTML返回和通过使用render方法来渲染模板 :

 

def showBook = {def b = Book.get(params.id)

render(template:"bookTemplate", model:[book:b])}

在客户端调用这个会涉及到remoteLink标签的使用 :

 

<g:remoteLink action="showBook" id="${book.id}" update="book${book.id}">Update Book</g:remoteLink><div id="book${book.id}">   <!--existing book mark-up --></div>

 

数据为中心的Ajax与JSON

数据为中心的Ajax通常涉及到客户端响应的赋值和编程化更新。Grails中的JSON响应,通常使用Grails的JSON marshaling能力 :

 

import grails.converters.*

def showBook = {def b = Book.get(params.id)

render b as JSON}

然后,在客户端使用一个Ajax事件处理解析这个进入的JSON请求:

 

<g:javascript>function updateBook(e) {var book = eval("("+e.responseText+")") // evaluate the JSON$("book"+book.id+"_title").innerHTML = book.title}<g:javascript><g:remoteLink action="test" update="foo" onSuccess="updateBook(e)">Update Book</g:remoteLink><g:set var="bookId">book${book.id}</g:set><div id="${bookId}"><div id="${bookId}_title">The Stand</div></div>

 

数据为中心的Ajax与XML

在服务器端使用XML同样普遍:

 

import grails.converters.*

def showBook = {def b = Book.get(params.id)

render b as XML}

不过,因为涉及到DOM,客户变得更复杂:

 

<g:javascript>function updateBook(e) {var xml = e.responseXMLvar id = xml.getElementsByTagName("book").getAttribute("id")$("book"+id+"_title")=xml.getElementsByTagName("title")[0].textContent}<g:javascript><g:remoteLink action="test" update="foo" onSuccess="updateBook(e)">Update Book</g:remoteLink><g:set var="bookId">book${book.id}</g:set><div id="${bookId}"><div id="${bookId}_title">The Stand</div></div>

 

脚本为中心的Ajax与JavaScript

脚本为中心的 Ajax涉及实际返回的Javascript在客户端被赋值。这样的示例见下表:

 

def showBook = {def b = Book.get(params.id)

response.contentType = "text/javascript" String title = b.title.encodeAsJavascript() render "$('book${b.id}_title')='${title}'"}

要记住的重要事情是,设置contentTypetext/javascript。如果在客户端使用Prototype,由于设置了contentType,返回的Javascript将自动被赋值.

很明显,在这种情况下,它是关键性的,你有一个一致的client-sideAPI,因此,你不想客户端的改变破坏服务器端。这就是Rails有些像RJS的理由之一。虽然,Grails当前没有像RJS的一个特性,但动态Dynamic JavaScript Plug-in插件提供了类似的能力. 

分享到:
0 0
原创粉丝点击