(Quick Reference)

6.7.1 Ajax支持 - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith

Version: null

6.7.1 Ajax支持

By default Grails ships with the jQuery library, but through the Plugin system provides support for other frameworks such as Prototype, Dojo:http://dojotoolkit.org/, Yahoo UI:http://developer.yahoo.com/yui/ and the Google Web Toolkit.

This section covers Grails' support for Ajax in general. To get started, add this line to the <head> tag of your page:

<g:javascript library="jquery" />

You can replace jQuery with any other library supplied by a plugin you have installed. This works because of Grails' support for adaptive tag libraries. Thanks to Grails' plugin system there is support for a number of different Ajax libraries including (but not limited to):

  • jQuery
  • Prototype
  • Dojo
  • YUI
  • MooTools

缺省情况下,Grails采用的是 jQuery 框架,但是通过其插件系统也提供了对其他框架的支持,比如Prototype、 Dojo:http://dojotoolkit.org/、Yahoo UI:http://developer.yahoo.com/yui/和Google Web Toolkit

本节将介绍Grails对Ajax的通用支持。在开始之前,请先在你页面的<head>标签部分增加如下内容:

<g:javascript library="jquery" />

因为Grails支持可适配的标签库,所以你可以用已经安装的其他框架来提到当前的jQuery。这要感谢Grails的插件系统,有了它才能支持这么多不同的Ajax框架库,包括但不限于如下所提到的:

  • jQuery
  • Prototype
  • Dojo
  • YUI
  • MooTools

6.7.1.1 异步超链接

Remote content can be loaded in a number of ways, the most commons way is through the remoteLink tag. This tag allows the creation of HTML anchor tags that perform an asynchronous request and optionally set the response in an element. The simplest way to create a remote link is as follows:

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

The above link sends an asynchronous request to the delete action of the current controller with an id of 1.

远程内容可以使用多种方法载入,最常使用的方法是通过remoteLink标签。此标签将创建HTML的锚标记用以执行一个异步请求,并在一个元素中设置响应内容。最简单的创建一个远程连接的方法如下:

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

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

6.7.1.2 更新内容

This is great, but usually you provide feedback to the user about what happened:

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

GSP code:

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

The above example will call the action and set the contents of the message div to the response in this case "Book 1 was deleted". This is done by the update attribute on the tag, which can also take a Map to indicate what should be updated on failure:

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

Here the error div will be updated if the request failed.

目前都还不错,但一般来说你会提供一些信息反馈给用户,以告诉都发生过什么,比如:

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>

上述示例将调用delete操作,并且将响应内容"Book 1 was deleted"设置到id为messagediv中,这是通过标签中的update属性来完成的。此外还可以用Map参数来设定失败时要更新那些,比如:

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

如果请求失败,那么此处的error将会被更新。

6.7.1.3 异步Form提交

An HTML form can also be submitted asynchronously in one of two ways. Firstly using the formRemote tag which expects similar attributes to those for the remoteLink tag:

<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 >

Or alternatively you can use the submitToRemote tag to create a submit button. This allows some buttons to submit remotely and some not depending on the action:

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

HTML的表单可以通过以下两种方式的一种进行异步提交。其一,使用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事件

Specific JavaScript can be called if certain events occur, all the events start with the "on" prefix and let you give feedback to the user where appropriate, or take other action:

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

The above code will execute the "showProgress()" function which may show a progress bar or whatever is appropriate. Other events include:

  • onSuccess - The JavaScript function to call if successful
  • onFailure - The JavaScript function to call if the call failed
  • on_ERROR_CODE - The JavaScript function to call to handle specified error codes (eg on404="alert('not found!')")
  • onUninitialized - The JavaScript function to call the a Ajax engine failed to initialise
  • onLoading - The JavaScript function to call when the remote function is loading the response
  • onLoaded - The JavaScript function to call when the remote function is completed loading the response
  • onComplete - The JavaScript function to call when the remote function is complete, including any updates

If you need a reference to the XmlHttpRequest object you can use the implicit event parameter e to obtain it:

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

当某个事件发生时,特定的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 - 处理特定的错误编码(比如on404="alert('not found!')")时要调用的JavaScript函数
  • onUninitialized - Ajax引擎初始化失败时要调用的JavaScript函数
  • onLoading - 远程调用正在加载响应时要调用的JavaScript函数
  • onLoaded - 远程调用已经加载完响应时要调用的JavaScript函数
  • onComplete - 远程调用完全结束(包括更新内容)时要调用的JavaScript函数

如果你需要使用XmlHttpRequest对象,你可以使用隐式的事件参数e来获取它:

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