书签 分享 收藏 举报 版权申诉 / 30

类型第11章集成 Ajax.docx

  • 文档编号:20132544
  • 上传时间:2023-04-25
  • 格式:DOCX
  • 页数:30
  • 大小:42.08KB

phpechojavascript_tag('

document.getElementById("indicator").innerHTML=

"Dataprocessingcomplete";

')?

>

symfony为此提供了一个名为update_element_function()的辅助函数,用于生成javascript代码而不是html代码。

例11-4是一个示例。

例11-4在javascript代码块中用update_element_function()辅助函数更新一个元素

Dataprocessingbeginning

phpechojavascript_tag('

update_element_function("indicator",array(

"content"=>"Dataprocessingcomplete",

'))

)?

>

你也许在想:

这条辅助函数语句和真正的javascript代码一样长,那使用它有什么特别的好处呢?

好处在于它的可读性。

例如,如果你想根据某种条件在一个元素之前或之后插入内容,或者不是更新元素内容而是删除一个元素,或者不做任何处理时,javascript代码将会变得相当混乱,但是利用update_element_function(),却可以像例11-5那样保持清晰易读。

例11-5update_element_function()辅助函数的选项

//在indicator元素之后插入内容

update_element_function('indicator',array(

'position'=>'after',

'content'=>"Dataprocessingcomplete",

));

//如果$condition成立,则删除indicator之前的元素

update_element_function('indicator',array(

'action'=>$condition?

'remove':

'empty',

'position'=>'before',

))

可以看出,这个辅助函数让你的模板比任何javascript代码都要容易理解,而且你只要使用一种语法就可以处理相似的行为。

这也是为什么这个辅助函数名字这样长的原因:

无需额外的说明,它就可以充分地解释自身的用途。

轻松地降级(GracefulDegradation)

symfony用一个辅助函数从另一方面进行补充这个功能,也就是利用它可以让代码仅在支持javascript的浏览器中执行。

例11-6中,显示了用if_javascript()和end_if_javascript()实现这种降级的用法:

例11-6利用if_javascript()辅助函数轻松地降级

phpif_javascript();?

>

YouhaveJavaScriptenabled.

phpend_if_javascript();?

>

Youdon'thaveJavaScriptenabled.

NOTE调用if_javascript()和end_if_javascript()时,不需要用echo.

Prototype

Prototype是一个优秀的javascript库,它扩展了客户端脚本的能力,增加了开发者想要的功能,并且提供了新的机制去操作DOM,该项目的网站是http:

//prototypejs.org/。

symfony框架中绑定了Prototype文件,在每个项目的web/sf/prototype目录中可以找到它的文件。

这样只要在你的action中增加下列代码就可以使用Prototype:

$prototypeDir=sfConfig:

:

get('sf_prototype_web_dir');

$this->getResponse()->addJavascript($prototypeDir.'/js/prototype');

或者在view.yml文件中加入:

all:

javascripts:

[%SF_PROTOTYPE_WEB_DIR%/js/prototype]

NOTE因为symfonyAjax辅助函数(下一节介绍)需要用到Prototype,所以只要你用到Prototype库,它就会自动被包含进来。

也就是说,如果你的模板调用一个_remote辅助函数,你无需在你的响应里手工添加PrototypeJavascript。

一旦你载入了Prototype库,就可以利用它为javascript核心增加的新函数。

本书的主要目的不是讲述这些函数,你可以很容易在互联网上找到所需的文档,以下是几个有关的网站:

∙Particletree:

∙SergioPereira:

∙Script.aculo.us:

http:

//wiki.script.aculo.us/scriptaculous/show/Prototype

Prototype新增的Javascript函数之一是$()函数。

简单地说,这个函数可以看成是document.getElementById()函数的缩写,但它有更强的功能。

例11-7给出了一个应用的例子。

例11-7利用$()函数根据DOM的元素ID取得元素值。

node=$('elementID');

//相当于

node=document.getElementById('elementID');

//也可以一次检索多个元素

//在本例中返回值是一个由DOM元素组成的数组。

nodes=$('firstDiv','secondDiv');

Prototype还提供了javascript核心真正缺乏的一个方法,这个方法返回所有CSSclassName属性等于它接收的参数的DOM元素组成的数组:

nodes=document.getElementByClassName('myclass');

当然你不太会用到这个函数,因为Prototype提供了一个更强大的$$()函数。

这个函数根据CSS选择器返回一个由DOM元素组成的数组。

所以前面的调用可以写成如下形式:

nodes=$$('.myclass');

凭借CSS选择器的作用,你可以根据class、ID、父子关系和前后关系去解析DOM,这比通过XPath表达式去解析更为简单。

你甚至可以用一个混合了所有这些选择器的复杂选择器去访问对应的元素。

nodes=$$('bodydiv#mainulli.lastimg>span.legend');

Prototype增强Javascript语法功能的最后一个例子是数组迭代。

它为Javascript定义匿名函数和闭包(closure)(译者注:

如果在一个javascript函数体中又出现一个函数定义时,称此函数为闭包(closure))功能提供了和PHP同样的简化形式。

如果你编写javascript代码,可能会大量用到这个功能。

varvegetables=['Carrots','Lettuce','Garlic'];

vegetables.each(function(food){alert('Ilove'+food);});

因为用Prototype编写Javascript比纯手工编写更为有趣,并且因为Prototype也是symfony的一个组成部分,所以你应该花些时间去研究它的文档。

Ajax辅助函数

如果你想在服务器端用PHP脚本去更新页面中的元素内容,而不想用javascript去更新(如例11-5所示),这样你可以根据一个服务器的响应来改变页面的某个部分,那该怎么做呢?

remote_function()辅助函数就可以完成这个任务,如例11-8所示:

例11-8应用remote_function()辅助函数

phpechojavascript_tag(

remote_function(array(

'update'=>'myzone',

'url'=>'mymodule/myaction',

))

)?

>

NOTEurl参数既可以包含一个内部URI(module/action?

key1=value1&…),也可以包含一个路由规则名,就像在一个标准的url_for()中那样。

当你调用这个函数时,这段脚本就会根据mymodule/myaction动作的请求或响应,去更新id为myzone的元素。

这种交互就是Ajax,也正是高度可交互的web应用的核心。

Wikipedia(http:

//en.wikipedia.org/wiki/AJAX)描述了Ajax的特点:

Ajax让页面只和服务器交换很少量的数据,因而每当用户改变页面时,不需要重新导入整个网页,而使得页面的响应更快。

也就是说增强了网页的交互性,速度和可用性。

Ajax依赖于javascript对象XMLHttpRequest,该对象的行为如同一个隐藏的帧,你可以从一个服务器请求更新它并且重用它去操纵页面的剩余部分。

这是一个相当底层的对象,不同的浏览器用不同的方法去处理它。

所幸的是,Prototype封装了所有Ajax需要的代码并提供了一个更为简化的Ajax对象,symfony就借助于这个对象。

这也是为什么当你在一个模板中使用Ajax辅助函数时,Prototype就会自动装入的原因。

CAUTION如果远程动作的URL不属于当前页所在的域,Ajax辅助函数将不工作。

这既是出于安全考虑,也受到浏览器禁止远程动作通过的限制。

一个Ajax交互由三个部分组成:

一个调用者(链接、按钮、表单、时钟或其它用户可以操纵以启动动作的任何控件),一个服务器动作和页面中的一个显示动作响应的区域。

如果远程动作返回的数据还要被客户端的Javascript函数处理,你可以创建更复杂的交互。

symfony提供了多个名字中包含remote的辅助函数,以便你在模板中插入Ajax交互。

它们使用共同的语法,可以将所有的Ajax参数放进一个关联数组中。

注意,Ajax辅助函数输出的是HTML,而不是Javascript。

SIDEBARAjax动作如何工作?

远程函数被调用的动作就是一个通常的动作。

与其它动作一样,它们可以被路由,可以确定用哪个视图提交它们返回的响应,也可以向模板传递参数以及改变模型等。

但是,当通过Ajax调用动作时,动作将返回true给下面的调用:

$isAjax=$this->isXmlHttpRequest();

symfony知道动作处于Ajax环境中,因而能够对响应做相应的处理。

因此,在默认情况下,开发环境中的Ajax动作不包含web调试工具栏,而且也会跳过装饰处理(默认情况下,模板不会被包含在布局中)。

如果你想装饰Ajax的视图,你需要在模块的view.yml文件中,为这个视图明确设置has_layout的值为true。

还有一点:

因为响应性在Ajax的交互中至关重要,所以如果响应不是非常复杂,最好不要创建视图,而是直接从动作返回响应。

这样你可以在动作中用renderText()方法,直接跳过模板而加速Ajax请求。

Ajax链接

在Web2.0应用中,Ajax链接是Ajax交互应用的主要内容。

显而易见,link_to_remote()辅助函数就可以输出一个调用远程函数的链接。

除了第二个参数是一个由Ajax选项组成的关联数组以外,其他语法类似于link_to()。

例11-9是一个示例。

例11-9利用ink_to_remote()辅助函数得到Ajax链接

phpecholink_to_remote('Deletethispost',array(

'update'=>'feedback',

'url'=>'post/delete?

id='.$post->getId(),

))?

>

在这个例子中,点击Deletethispost链接就会在后台发出一个对post/delete的调用。

从服务器返回的响应将出现在id为feedback的元素中。

图11-1显示了运行的过程。

图11-1用链接触发一个远程更新

对于链接,你可以用图片代替字符串,用规则名代替内部的模块/动作URL,还可以将选项加进标记的第三个参数中。

如例11-10所示。

例11-10link_to_remote()辅助函数的选项

phpecholink_to_remote(image_tag('refresh'),array(

'update'=>'emails',

'url'=>'@list_emails',

),array(

'class'=>'ajax_link',

))?

>

Ajax驱动的表单

Web表单一般要调用另一个动作,但这会导致整个页面被刷新。

对表单来说,类似于link_to_function()可以在表单提交后,仅用服务器的响应去更新页面中的一个元素,form_remote_tag()辅助函数就是完成这个任务的,例11-11展示了它的语法:

例11-11利用form_remote_tag()辅助函数得到Ajax表单

phpechoform_remote_tag(array(

'update'=>'item_list',

'url'=>'item/add',

))?

>

Item:

phpechoinput_tag('item')?

>

phpechosubmit_tag('Add')?

>

就像form_tag()辅助函数一样,form_remote_tag()也打开一个

提交这个表单会在后台向item/add动作发出一个POST请求,请求参数就是item字段的内容。

响应会替换item_list元素的内容(如图11-2所示)。

最后用通常的

标记关闭Ajax表单。

图11-2利用表单触发远程更新.

CAUTION由于XMLHttpRequest对象的限制,Ajax表单不可以分为多个部分。

这意味着你不能通过Ajax表单上传文件。

不过你可以用其他方法解决这个问题—比如,用隐式的iframe代替XMLHttpRequest(参看

如果你想让一个表单同时工作在页面模式和Ajax模式,最好的方法是定义一个通常的表单,然后除了提供通用的提交按钮,再增加一个按钮()用于以Ajax方式提交表单。

symfony用submit_to_remote()调用这个按钮。

这可以帮助你建立一个可以轻松降级的Ajax交互表单,即可以与不支持Javascript的浏览器兼容。

见例11-12所示。

例11-12具有普通提交方式和Ajax提交方式的表单

phpechoform_tag('@item_add_regular')?

>

Item:

phpechoinput_tag('item')?

>

phpif_javascript();?

>

phpechosubmit_to_remote('ajax_submit','AddinAjax',array(

'update'=>'item_list',

'url'=>'@item_add',

))?

>

phpend_if_javascript();?

>

phpechosubmit_tag('Add')?

>

另一个混合了普通提交和Ajax提交标记的例子是编辑文章的表单。

它可以提供一个实现了Ajax的预览按钮和一个用普通提交实现的发布按钮。

NOTE当用户按下回车键时,表单会用定义在主

标记中的动作去提交,在本例中,就是普通提交动作。

窗体顶端

现代表单不仅仅在提交时作出回应,在用户改变某个域的值时也会有回应。

在symfony中,你可以用observe_field()辅助函数来实现这个功能。

例11-13应用这个辅助函数建立一个具有建议特性的页面,也就是在item字段中每输入一个字符,都会触发一次Ajax调用去刷新页面中的item_suggestion元素。

例11-13当字段值变化时,observe_field()调用一个远程函数

phpechoform_tag('@item_add_regular')?

>

Item

举报
举报
版权申诉
版权申诉
word格式文档无特别注明外均可编辑修改;预览文档经过压缩,下载后原文更清晰! 立即下载
配套讲稿:

如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

特殊限制:

部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

关 键  词:
第11章 集成 Ajax 11
提示  冰豆网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
关于本文
本文标题:第11章集成 Ajax.docx
链接地址:https://www.bdocx.com/doc/20132544.html

copyright@ 2008-2022 冰点文档网站版权所有

经营许可证编号:鄂ICP备2022015515号-1

收起
展开