Grails WEB层 AJAX

 

6.7 Ajax

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

6.7.1 用Prototype实现Ajax

Grails默认装载Prototype 库,但通过Plug-in 系统,可以提供对Dojo, Yahoo UIGoogle 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, formRemotesubmitToRemote标签都可以和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.responseXML
	var 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插件提供了类似的能力. 

你可能感兴趣的:(JavaScript,Ajax,Web,grails,dojo)