AJAX in CakePHP
Cake 中的 AJAX 实质
CakePHP(以下简称“Cake”,本文使用的版本是 0.10.7.1856 RC3)对 AJAX 的支持是建立在 prototype 与 script.aculo.us 之上的,其自身并没有包含服务器端、客户端的 AJAX 实现,所以想要在 Cake 中熟练地使用 AJAX,必须首先熟悉 prototype 和 script.aculo.us,而本文的重点并不是这两个出众的 JavaScript 库。说白了,Cake 实际上只是简化了繁琐的 AJAX JavaScript 代码。
Cake 中的 AJAX 相关文件
在 Cake 中,与 AJAX 相关的文件只有两个:
- cake/cake/libs/view/templates/layouts/ajax.thtml
- cake/cake/libs/view/helpers/ajax.php
ajax.thtml 文件是执行 AJAX 动作之后用于输出的布局,和一般的布局文件不同的是它是一个空的布局视图文件,没有 header/footer 等等内容。ajax.php 文件则是用于 Cake 视图文件的 AJAX 辅助类 AjaxHelper,此类中包含了很多 AJAX 动作的相关方法,详细 API 请参考 http://api.cakephp.org/class_ajax_helper.html。
除了上述的两个文件外,我们还需要 Prototype 的 prototype.js 和 script.aculo.us 中的 *.js 文件,这些文件可在官方网站上下载到,将这些 *.js 文件放置 cake/app/webroot/js/ 目录下即可。对于这两个库,本文用的版本分别是 1.4.0 和 1.5.1。
Hello, AJAX world!
现在我们使用一个简单的示例简单演示一下如何在 Cake 中使用 AJAX。这个示例将实现点击链接之后,在页面上加载服务器端输出的“Hello, AJAX world!”信息。为了简单起见,示例中不使用任何数据库,也就是不用 Cake 的模型(Model),而只用控制器(Controller)和视图(View)。首先创建一个布局视图文件 cake/app/views/layouts/demo.thtml,用于自定义布局以及加载需要用到的 JavaScript 文件,此文件内容如下:
<!DOCTYPEhtmlPUBLIC”-//W3C//DTDXHTML1.0Transitional//EN”
”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<htmlxmlns=”http://www.w3.org/1999/xhtml”>
<head>
<title>CakePHPAJAXDemo::<?phpecho$title_for_layout?></title>
<?phpecho$html->charsetTag(‘UTF-8′)?>
<?phpecho$javascript->link(‘prototype’)?>
<?phpecho$javascript->link(’scriptaculous’)?>
</head>
<body>
<divid=”container”>
<center><h2>CakePHPAJAXDemo</h2></center>
<divid=”content”><?phpecho$content_for_layout?></div>
</div>
</body>
</html>
重点在于 $javascript->link() 的那两行,包含了需要用到的 JavaScript 文件 prototype.js 和 scriptaculous.js,而 script.aculo.us 库中的其他 JavaScript 文件都由 scriptaculous.js 统一进行包含,不用我们书写额外的代码,如果并不想使用 script.aculo.us 的所有 js 文件,可以使用 load 参数进行指定包含,比如我们只用到 effects.js,可以这样(多个则用英文逗号“,”分割开):
<?phpecho$javascript->link(’scriptaculous.js?load=effects’)?>
接下来是创建一个控制器文件 cake/app/controllers/demos_controller.php:
<?php
classDemosControllerextendsAppController
{
var$name=‘Demos’;//兼容PHP4
var$layout=‘demo’;//指定视图使用的布局为demo.thtml
var$helpers=array(‘Html’,‘Javascript’,‘Ajax’);//需要用到的视图辅助类
functionindex()
{
}
functionhello()
{
sleep(1);//本地测试时,为了更好地看到效果,模拟延迟状态
$this->layout=‘ajax’;//此方法为AJAX动作,所以布局需要使用ajax.thtml
}
}///:~
?>
此控制器的重点有三个:
- 设置默认布局为 demo.thtml,这样才能在 index 视图中使用 prototype.js 等
- 在视图辅助类数组 $helpers 中加上“Ajax”辅助类
- 对于 AJAX 动作方法 hello() 需要将其当前布局设置为“ajax”
对应于控制器中的两个方法(Action),我们需要在 cake/app/views/demos/ 目录下创建两个视图文件:index.thtml 和 hello.thtml。
index.thtml:
<divid=”loading”style=”display:none;padding:4px;color:black;
background-color:#FAD163;width:100px”><strong>Loading…</strong></div>
<divid=”view”style=”display:none;background-color:#E8EEF7;
padding:4px;border:1pxsolidsilver;width:300px”></div>
<p>
<?php
//设置AJAX选项
$options=array(
//设置加载成功之后需要进行更新的元素为view
‘update’=>‘view’,
//加载过程中隐藏view元素,显示“Loading…”字样
‘loading’=>“Element.hide(’view’);Element.show(’loading’)”,
//加载成功之后隐藏loading,同时显示view元素
‘complete’=>“Element.hide(’loading’);Effect.Appear(’view’)”
);
//使用AjaxHelper创建AJAX动作链接
echo$ajax->link(‘Clickhere!’,‘/demos/hello’,$options);
?>
</p>
这个视图中有三个元素:loading、view 与 AJAX 链接。初始状态下 loading 与 view 是隐藏的(display:none),只有点击了 AJAX 链接之后,在加载状态中显示 loading,加载完成之后将其隐藏,然后显示 view,“Hello, AJAX world!”即显示在 view 中。此视图的重点在于 $ajax->link(),$ajax 是 AjaxHelper 的对象实例,link() 方法的第一个参数是链接显示的文本,第二个参数是 Cake 的 URL,这里的 URL 为 /demos/hello,指向了 AJAX 动作方法 hello(),此动作最终输出视图 hello.thtml,第三个参数为 AJAX 选项,Cake 会自动根据选项生成链接中使用到的 JavaScript 代码。对于一个简单的 AJAX 动作,主要就是设置三个选项:update、loading 与 complete,这几个选项的意义在视图代码的注释中都有了详细说明。
最后就是 hello.thtml 视图文件了,只是一行简单的文本:
<center>Hello,AJAXworld!</center>
OK,通过尽量少的编码,我们完成了这个示例,可以通过 http://www.somesite.com/cake/demos/ 浏览最终效果。
Live Search
Live Search 指的是即时查询,通常是用户在文本框中输入想要查询的关键字,由客户端 JavaScript 对文本框进行观察,监测到用户输入之后即时提交到服务器,并显示服务器返回的结果。接下来我们将使用 Cake 的 AJAX 实现 Live Search,从一个数组中获取符合查询关键字的数据,然后即时更新到页面中。
首先修改我们的控制器 demos_controller.php,增加一个方法 search():
<?php
functionsearch()
{
$langs=array(
‘C’,‘C++’,‘C#’,
‘Java’,‘JavaScript’,
‘PHP’,‘Perl’,‘Python’,
‘Ruby’,‘Delphi’);
$this->layout=‘ajax’;
if(empty($this->params[‘form’][‘livesearch’])){//未提交任何数据
$result=$langs;
}else{//根据提交的关键字进行查询
$word=$this->params[‘form’][‘livesearch’];
$result=array();
foreach($langsas$lang)
if(stristr($lang,$word)!==false)
$result[]=$lang;
}
$this->set(‘result’,$result);
}
?>
在 index.thtml 视图文件中,加入 Live Search 的表单代码:
<formonsubmit=”returnfalse”>
<p>
<b>LiveSearch:</b>
<inputtype=”text”name=”livesearch”id=”livesearch”/>
</p>
</form>
<?php
//设置AJAX选项
$options=array(
‘update’=>‘view’,
//处理查询的URL,对应于控制器中的search()方法
‘url’=>‘/demos/search’,
//观察频率,单位为“秒”
‘frequency’=>1,
‘loading’=>“Element.hide(’view’);Element.show(’loading’)”,
‘complete’=>“Element.hide(’loading’);Effect.Appear(’view’)”
);
echo$ajax->observeField(‘livesearch’,$options);
?>
这里用到了 AjaxHelper 中的另一个方法 observeField(),此方法用于观察某个元素的数据是否发生变化,发生变化时则调用相应的 AJAX 操作。方法的第一个参数为需要观察的元素 id,这里是“livesearch”文本框,第二个参数为 AJAX 选项,和 link() 方法中的相似,只不过这里的选项设置多了 url 与 frequency,url 即 Cake 的 URL,对应于控制器中的方法,frequency 则是观察的间隔时间,单位为“秒”,即每隔多少秒查看一下对应的元素是否发生了改变。
对应于 search() 方法,创建视图文件 cake/app/views/demos/search.thtml:
<?phpif(count($result)>0):?>
<ul>
<?phpforeach($resultas$lang):?>
<li><?phpecho$lang?></li>
<?phpendforeach?>
</ul>
<?phpelse:?>
<fontcolor=”gray”>Foundnothing!</font>
<?phpendif?>
好了,这个 Live Search 已经完成了,是不是很简单 现在只要在文本框中输入字符,就会在 $langs 数组中查找,只要包含了查询关键字的结果都会被返回并更新到 view 元素中。
其他应用
Cake 的 AjaxHelper 中还提供了很多方法,如用于拖曳的 drag()、drop() 及 dropRemote();用于排序的 sortable();用于自动完成的 autoComplete() 等等,由于涉及到的讲解篇幅比较大,暂时就不深入了,有时间的话我再一一道来。drag/drop 可以在我写的 Cake Framework AJAX Demo 中看到在线演示,并可下载到源代码。
一些问题
Cake 当前版本(0.10.7.1856 RC3)的一些方法还不是非常完善,对于最新版本的 script.aculo.us 库中的一些参数还不支持,相信很快会得到更新。实际应用中可能会碰到中文乱码的问题,那是因为 XMLHttpRequest 获取到的数据都是以 UTF-8 编码的,所以解决的办法有两个,一个是所有页面、数据库数据均使用 UTF-8 编码,这样可以省去很多麻烦,另外一个就是通过 PHP 的 iconv() 函数进行转码,但这需要用到 iconv 扩展,所以比较麻烦一些,而且无形中为服务器增加了额外的负担。
相关推荐
This is a simple demo of some of the AJAX helpers now available in CAKE. These helpers are directly modeled on Ruby On Rails. In fact, they were shamelessly ported from rails almost verbatim. You can ...
在cakephp.org站点的Sites in the wild页面可以看到当前使用CakePHP框架的网站列表。 CakePHP 是一个运用了诸如ActiveRecord、Association Data Mapping、Front Controller和MVC等著名设计模式的快速开发框架。该...
在cakephp.org站点的Sites in the wild页面可以看到当前使用CakePHP框架的网站列表。 CakePHP 是一个运用了诸如ActiveRecord、Association Data Mapping、Front Controller和MVC等著名设计模式的快速开发框架。该...
在cakephp.org站点的Sites in the wild页面可以看到当前使用CakePHP框架的网站列表。CakePHP 是一个运用了诸如ActiveRecord、Association Data Mapping、Front Controller和MVC等著名设计模式的快速开发框架。该项目...
在cakephp.org站点的Sites in the wild页面可以看到当前使用CakePHP框架的网站列表。 CakePHP 是一个运用了诸如ActiveRecord、Association Data Mapping、Front Controller和MVC等著名设计模式的快速开发框架。该...
在cakephp.org站点的Sites in the wild页面可以看到当前使用CakePHP框架的网站列表。 CakePHP 是一个运用了诸如ActiveRecord、Association Data Mapping、Front Controller和MVC等著名设计模式的快速开发框架。该...
在cakephp.org站点的Sites in the wild页面可以看到当前使用CakePHP框架的网站列表。</p><p>CakePHP 是一个运用了诸如ActiveRecord、Association Data Mapping、Front Controller和MVC等著名设计模式的快速开发框架...
- **CakePHP**: 基于常见设计模式的快速开发框架,易于上手。 - **PHPDevShell**: 用于开发不含JavaScript的纯PHP应用程序,强调速度、安全性和稳定性。 #### 总结 以上列举的面试题目涵盖了从 HTML/CSS 到 ...