1. Ajax的起源和发展:花开两朵,各表一枝。话说当年微软为了让自己的web版Outlook看起来和桌面应用差不多,就把Ajax作成了IE浏览器的一个ActivX插件,然后通过JavaScript调用它进行异步的浏览器request。大家一看觉得不错,于是把它进一步标准化,产生了一个叫XMLHttpRequest的本地JavaScript对象,用来支持其他的浏览器,从而激发了Web 2.0的革命!微软在IE 7.0开始支持XMLHttpRequest作为本地对象,但是6.0里还是ActivX插件,所以在编码时还得先检测浏览器,再确定其加载方式。例如:
var req=null;
if(window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
2. 继续上面的代码,利用回调事件onreadystatechange来触发一个函数(例子中的processRequest)对response对象进行异步处理:
req.onreadystatechange = processRequest;
req.open("GET","
http://localhost:8080/a/remote/location
", true);
req.send();
function processRequest(obj) {
alert(obj.responseXML)
}
整个过程如下:
* 浏览器调用JavaScript
* JavaScript产生XMLHttpRequest对象req
* 通过XMLHttpRequest对象req发送一个request到服务器
* 服务器返回XML Response到XMLHttpRequest对象
* XMLHttpRequest对象触发JavaScript中的回调函数processRequest
* processRequest执行产生一个alert。
3. 上述的代码显然比较繁琐,于是出现了很多Ajax框架来对一些逻辑进行封装,从简单的Prototype到全面的Dojo。grails则提供了一个灵活的配置,允许开发者自定义使用哪个Ajax库(缺省是Prototype)。
使用Prototype需要在index.gsp的<head>定义一个g:javascript标签:
<g:javascript library="prototype"/>
这样Prototype就会自动加载所有dependencies使之可用。
4. 在此之后,可以在.gsp中使用g:remoteLink标签在页面HTML生成一个tag,点击的时候就执行一个异步请求给对应的controller / action,然后把服务器返回的response内容加载到标签中指定的update属性对应的DOM ID中。例如:
<g:remoteLink action="showTime" update="time">Show the time!</g:remoteLink>
<div id="time">
</div>
5. 变更Ajax库:很简单,只需要在index.gsp的<head>修改g:javascript标签即可,如:<g:javascript library="yui"/>,就可以了。
6. 异步表单提交:使用g:formRemote标签,定义类似于g:remoteLink的参数,把需要刷新的页面部分单独做成一个gsp template,然后在gsp页面的div和controller的action中指定render该template即可。
7. before和after属性:每个Ajax标签都支持这两个属性,对应在远程调用之前和之后插入任意的JavaScript代码进行执行。例如:
<g:formRemote action="login"
before="setDefaultValue(this);"
update="loginBox"
name="loginForm">
...
</g:formRemote>
注意:before和after不是事件的钩子,特别是after的执行是紧接着Ajax call之后,并不需要等待其返回,甚至Ajax call没有成功它也照样会执行。
8. 处理事件:在grails的Ajax标签中可以登记多个不同的事件处理项,例如:
<g:formRemote url="[controller:'user', action:'login']"
onLoading="showProgress();"
onComplete="hideProgress();"
update="loginBox"
name="loginForm">
...
</g:formRemote>
事件包括:onSuccess, onFailure, onLoaded, onComplete, onERROR_CODE。在Prototype里有总体性响应机制,可以把Ajax的事件逻辑集中化,从而可以让所有的Ajax调用都具有统一的表现特性。
9. 动画效果:可以用Scriptaculous库,然后利用Ajax事件如onComplete,配合<g:remoteLink>标签来激活动画效果,但是这样做需要在每个<g:remoteLink>里都要包含onComplete之类的事件处理,更好的做法是在template中直接嵌入script,如:
<g:javascript>
Effect.Appear($('album${album.id}'))
</g:javascript>
这样就会在template中增加Scriptaculous库中的Appear效果。推荐通过这种方式来实现淡入淡出等动画效果。
10. 支持Ajax的表单域:<g:remoteField>是一个文字域,可以在其中的值发生任何变化时发送到服务器,可以用于自动化的动态查询。例如:
<div id="searchBox">
Instant Search:
<g:remoteField name="searchBox"
update="musicPanel"
paramName="q"
url="[controller:'store', action:'search']"/>
</div>
配合grails的Searchable插件(在Compass和Lucene的基础上开发的),安装好之后在需要进行动态查询的Domain类中增加一行:
static searchable = true,即可对整个Domain类的数据进行模糊查询。如果要对Domain类中的一个属性子集甚至一个属性进行更加精准的查询,Searchable也提供了一套DSL用于映射Domain类和查询索引,例如:
class User{
static searchable = [only:['name','title']]
...
}
然后就是在controller里实现search action。如同GORM一样,Searchable提供了一整套新的方法来支持查询,包括:
search:返回一个查询结果对象,其中包含一个查询到的对象子集
searchTop:返回符合查询条件的第一个对象
searchEvery:返回符合查询条件的所有对象
countHits:返回查询到的记录数
termFreqs:返回每个索引项出现的频率
使用它们进行查询action的例子:
def search ={
def q=params.q?:null
def searchResults
if(q){
searchResults = [
albumResults:trySearch{ album.search(q,[max:10])},
q:q.encodeAsHTML()
]
}
render(template:"searchResults",model:searchResults)
}
def trySearch(Closure callable) {
try{
return callable.call()
}
catch(Exception e) {
log.debug "search error: ${e.message}",e
return []
}
}
11. 关于Ajax的性能问题:由于涉及到前后端的交互,Ajax应用需要付出性能成本。需要render的代码块越多,Ajax应用就需要处理越多的request。可以采用EJB里的一些特性如DTO(Data Transfer Object)来优化远程方法调用,可以把批量操作整合为单个的调用,经验证明,一次传输大量的数据比把它分拆为很多小的数据在性能上往往有明显的改进;此外,通过缓存技术把一部分处理转移到Ajax客户端也是行之有效的方法。
分享到:
相关推荐
The definitive guide to grails 2 英文版 书和随书代码, 学习grails必备
The definitive guide to Grails是一部Grails开发技术的经典书籍。这是网上关于该书的一些学习笔记,一共八篇,比较精炼,值得一读。
详细介绍grails框架的奥秘,英文版你值得拥有
The Definitive Guide to Grails 2nd Edition.pdf
The definitive guide to grails_2 随书 源代码
The Definitive Guide to Java Swing Third Edition
The Definitive Guide to Django 2nd Edition 本书分为两部分 第一部分可以视为入门 第二部分深入 对使用Django系统及想要使用的很有帮助 英文
The Definitive Guide to Spring Batch takes you from the “Hello, World!” of batch processing to complex scenarios demonstrating cloud native techniques for developing batch applications to be run on...
The Definitive Guide to Jython, written by the official Jython team leads, covers the latest Jython 2.5 (or 2.5.x) from the basics to the advanced features. This book begins with a brief introduction ...
书由Apress出版社出版发行,“Definitive Guide”系列丛书之一。这本书是介绍MySQL 5的权威手册,初学者可以以此开始学习MySQL数据库技术。
The most up-to-date comprehensive guide to use Grails for rapid web development. 最新最全版本使用Grails进行快速web应用程序开发。英文版。原汁原味,通俗易懂。由Grails项目组组长亲自编写,涉及Grails的每...
And because SQLite's databases are completely file based, privileges are granted at the operating system level, allowing for easy and fast user management., The Definitive Guide to SQLite is the ...
The Definitive Guide to SQLite (Second Edition)
The Definitive Guide to NetBeans Platform 7
The Definitive Guide to Windows Installer Introduction Chapter 1 - Installations Past, Present, and Future Chapter 2 - Building an Msi File: Visual Studio and Orca Chapter 3 - COM in the ...
The Definitive Guide to Django - Web Development Done Right(2nd) 英文无水印pdf 第2版 pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 ...
The Definitive Guide to the ARM® Cortex®-M0 and Cortex-M0+ Processors, Second Edition explains the architectures underneath ARM’s Cortex-M0 and Cortex-M0+ processors and their programming ...
The Definitive Guide to GCC, Second Edition has been revised to reflect the changes made in the most recent major GCC release, version 4. Providing in-depth information on GCC’s enormous array of ...
The Definitive Guide to SQLite是市面上唯一的讲SQLite3的书,而且内容很新,资源是书中示例的源码。