让你的Sylius专业知识得到认可< / >< / p >< / div >< / div > ob娱乐下载Symfony代码性能分析< / >< / p >< / div >< / div > 接受SensioLabs专家的培训(2 - 6天的课程-法语或英语)。< / >< / p >< / div >< / div > ob娱乐下载Symfony的会议< / p > ob娱乐下载SymfonyOnline 2023年6月< / > 2023年6月15日至16日< / div >< / div >< / div > ob娱乐下载SymfonyLive巴黎2023< / > 2023年3月23日至24日< / div >< / div >< / div >< / div >< / div >< / div > 基本JavaScript助手< / >< ul ><李>模板中的JavaScript< / > 更新DOM元素< / > 优雅降级< / > 原型< / > Ajax助手< / >< ul ><李>Ajax链接< / > ajax开发的形式< / > 定期调用远程函数< / > 远程呼叫参数< / >< ul ><李>根据响应状态更新不同的元素< / > 根据位置更新元素< / > 根据条件更新元素< / > 确定Ajax请求方法< / > 授权脚本执行< / > 创建回调< / > 创造视觉效果< / > JSON< / > 使用Ajax执行复杂交互< / >< ul ><李>自动完成< / > 拖放< / > 可排序的列表< / > 就地编辑< / > 总结< / > 客户端交互、复杂的视觉效果和异步通信在Web 2.0应用程序中很常见。所有这些都需要JavaScript,但是手动编写代码通常很麻烦,调试也很耗时。幸运的是,symfony通ob娱乐下载过一组完整的助手自动化了模板中JavaScript的许多常见用法。许多客户端行为甚至不需要一行JavaScript就可以编码。开发人员只需要担心他们想要达到的效果,而symfony将处理复杂的语法和兼容性问题。ob娱乐下载< / p >< p >本章描述symfony提供的方便客户端脚本编写的工具:ob娱乐下载< / p >< ul ><李>基本的JavaScript helper输出符合标准<脚本>标记,以更新文档ob娱乐下载对象模型(DOM)元素或触发带有链接的脚本。 Prototype是一个集成在symfony中的JavaScript库,它通过向JavaScriob娱乐下载pt核心添加新函数和方法来加快客户端脚本开发。 Ajax帮助程序允许用户通过单击链接、提交表单或修改表单元素来更新页面的某些部分。 这些helper的许多选项提供了更大的灵活性和功能,特别是通过使用回调函数。 us是另一个JavaScript库,也集成在symfony中,它添加了动态视觉效果来增强界面和用户体验。ob娱乐下载 JavaScript对象符号(JSON)是用于服务器和客户端脚本之间通信的标准。 在symfony应用程序中,组合了上述所有元素的复杂客户端交互是可能的。ob娱乐下载自动补全、拖放、可排序列表和可编辑文本都可以通过一行PHP实现——调用symfony助手。ob娱乐下载 基本JavaScript助手< / > 由于缺乏跨浏览器兼容性,JavaScript一直被认为在专业的web应用程序中几乎没有实际用途。今天,兼容性问题(大部分)得到了解决,一些健壮的库允许您用JavaScript编写复杂的交互程序,而不需要无数行代码,也不需要花费数小时的调试时间。最流行的改进叫做Ajax,这将在本章后面的“Ajax助手”一节中讨论。< / p >< p >矛盾的是,在本章中您将看到很少的JavaScript代码。这是因为symfony有一种原始ob娱乐下载的客户端脚本编写方法:它将JavaScript行为打包并抽象到helper中,因此您的模板最终根本不显示JavaScript代码。对于开发人员来说,向页面中的元素添加一个行为只需要一行PHP,但是这个助手调用会输出JavaScript代码,检查生成的响应将揭示所有封装的复杂性。helper处理浏览器一致性、复杂的极限情况、可扩展性等等,因此它们所包含的JavaScript代码量可能相当重要。因此,本章将教你如何不使用JavaScript来实现你用JavaScript构建的效果。< / p >< p >类的使用,这里描述的所有帮助程序都可以在模板中使用Javascript辅助组。< / p > <?phpuse_helper(Javascript的)? > 您很快就会了解到,这些帮助程序中有些输出HTML代码,有些输出JavaScript代码。< / p >模板中的JavaScript< / > 在XHTML中,JavaScript代码块必须包含在CDATA声明中。但是需要多个JavaScript代码块的页面很快就会变得冗长乏味。这就是symfony提ob娱乐下载供javascript_tag ()helper,它将字符串转换为xhtml兼容的格式<脚本>标签。清单11-1演示了如何使用这个helper。< / p >清单11-1 -使用javascript_tag ()助手< / p > <?php回声javascript_tag(函数foobar(){…}”)? >=> <脚本类型=“text / javascript”>/ / < ![CDATA[函数foobar(){...}/ /]] >> < /脚本 但是JavaScript最常见的用途(而不是代码块)是在触发特定脚本的超链接中。的link_to_function ()helper正是这样做的,如清单11-2所示。< / p >清单11-2 -通过链接触发JavaScriptlink_to_function ()助手< / p > <?php回声link_to_function(“点击我!”,“警报(“foobar”)”)? >=> “#”onClick =“警报(“foobar”);返回none”;>点击我!< / > 就像link_to ()助手,您可以向<一>标记在第三个参数中。< / p > 请注意< / p >< p >就像link_to ()助手有一个button_to ()兄弟,你可以从一个按钮触发JavaScript (< input type = " button " >),即致电button_to_function ()帮手。如果你喜欢可点击的图片,就打电话link_to_function (image_tag(“模板”),“警报(“foobar”)”).< / p >< / div >< / div >更新DOM元素< / > 动态接口中的一个常见任务是更新页面中的元素。这是您通常编写的如清单11-3所示的内容。< / p >清单11-3 -在JavaScript中更新元素< / p > < div id =“指标”>数据处理开始 . b<?php回声javascript_tag(. getelementbyid (指示器”)。innerHTML = "数据处理完成 .”;“)? > ob娱乐下载Symfony为此目的提供了一个生成JavaScript而不是HTML的帮助器,它被称为update_element_function ().清单11-4展示了它的用法。< / p >清单11-4 -在JavaScript中使用update_element_function ()助手< / p > < div id =“指标”>数据处理开始 . b<?php回声javascript_tag(update_element_function(“指标”,数组(“内容”= >"数据处理完成",)))? > 您可能想知道为什么这个helper特别有用,因为它至少和实际的JavaScript代码一样长。这其实是可读性的问题。例如,您可能希望在元素之前或之后插入内容,删除元素而不只是更新它,甚至根据特定条件什么都不做。在这种情况下,JavaScript代码会变得有些混乱,但是update_element_function ()保持模板的可读性,如清单11-5所示。< / p >清单11-5 -选项update_element_function ()助手< / p > //在'indicator'元素后面插入内容update_element_function(“指标”,数组(“位置”= >“后”,“内容”= >"数据处理完成",));//删除'indicator'前面的元素,并且仅当$condition为真时update_element_function(“指标”,数组(“行动”= >美元的条件?“删除”:“空”,“位置”= >“之前”,)) helper使您的模板比任何JavaScript代码都更容易理解,并且对于类似的行为您有单一的语法。这也是helper名称如此长的原因:它使代码自给自足,不需要额外的注释。< / p >优雅降级< / > 的< noscript >标签允许您指定一些HTML代码,这些代码只在不支持JavaScript的浏览器上显示。ob娱乐下载Symfony用另一种方式工作的帮助器补充了这一点:它限定了一些代码,以便只有真正支持JavaScript的浏览器才能执行它。的if_javascript ()而且end_if_javascript ()helper有助于创建能够优雅降级的应用程序,如清单11-6所示。< / p >清单11-6 -使用if_javascript ()允许优雅降级的助手< / p > <?phpif_javascript();? >你已经启用了JavaScript<?phpend_if_javascript();? > 你不没有启用JavaScript。< / p > < / noscript > 请注意< / p >< p >你不需要包含回声当致电if_javascript ()而且end_if_javascript ()帮手。< / p >< / div >< / div >原型< / > Prototype是一个很棒的JavaScript库,它扩展了客户端脚本语言的可能性,添加了您一直梦想的缺失函数,并提供了操作DOM的新机制。项目网址为http://prototypejs.org/< / >.< / p >< p >原型文件与symfony框架捆绑在一起,可以在每个新的symfonyob娱乐下载项目中访问web /科幻/原型/.这意味着你可以通过在动作中添加以下代码来使用Prototype:< / p > prototypeDir美元= sfConfig::得到(“sf_prototype_web_dir”);这个美元->getResponse()->addJavascript(prototypeDir美元./ js /原型的); 或者把它加到view.yml文件:< / p > 所有:javascript脚本:[%SF_PROTOTYPE_WEB_DIR%/js/prototype] 请注意< / p >< p >由于下一节将介绍的sob娱乐下载ymfony Ajax助手依赖于Prototype,因此只要您使用其中的一个,Prototype库就已经自动包含在内了。这意味着如果您的模板调用一个,您不需要手动将Prototype JavaScript添加到响应中_remote帮手。< / p >< / div >< / div >< p >一旦Prototype库被加载,您就可以利用它添加到JavaScript核心中的所有新函数。这本书的目的不是要描述它们,但是你可以很容易地在网络上找到关于Prototype的好的文档,包括以下网站:欧宝官网下载app< / p >< ul ><李>Particletree:http://particletree.com/features/quick-guide-to-prototype/< / > 塞尔吉奥·佩雷拉:http://www.sergiopereira.com/articles/prototype.js.html< / > Script.aculo.us:http://wiki.script.aculo.us/scriptaculous/show/Prototype< / > Prototype添加到JavaScript的一个函数是美元函数,$ ().基本上,这个函数是一个简单的快捷方式. getelementbyid (),但更强大一点。清单11-7给出了它的使用示例。< / p >清单11-7 -使用$ ()JavaScript中通过ID获取元素的函数< / p > 节点= $(“elementID”);//与node = document.getElementById(“elementID”);//它也可以同时检索多个元素//在这种情况下,结果是一个DOM元素数组Nodes = $(“firstDiv”,“secondDiv”); Prototype还提供了一个JavaScript核心所缺少的函数,该函数返回一个数组,其中包含所有将类作为参数传递的DOM元素:< / p > nodes = document.getElementByClassName(“myclass”); 然而,你很少会使用它,因为Prototype提供了一个更强大的功能,叫做double dollar,$ $ ().这个函数根据CSS选择器返回一个DOM元素数组。所以前面的调用也可以写成这样:< / p > 节点= $$(“.myclass”); 由于CSS选择器的强大功能,您可以比使用XPath表达式更容易地按类、ID、父子关系和上下关系解析DOM。你甚至可以使用一个复杂的选择器来访问这些元素:< / p > 节点= $$('体div#主ul li。最后一个img > span.legend'); Prototype提供的语法增强的最后一个例子是each数组迭代器。除了在JavaScript中定义匿名函数和闭包之外,它还提供了与PHP中相同的简洁。如果您手工编写JavaScript,可能会经常使用它。< / p > var蔬菜=[“胡萝卜”,“莴苣”,“大蒜”];蔬菜。每一个(函数(食物){警报(“我爱”+食物);}); 因为使用Prototype在JavaScript中编程要比手工编写有趣得多,而且它也是symfony的一部分,所以您真的应该花几分钟阅读相关文档。欧宝官网下载appob娱乐下载< / p >Ajax助手< / > 如果您希望更新页面中的元素,而不是使用清单11-5所示的JavaScript,而是使用服务器执行的PHP脚本,该怎么办?这将使您有机会根据服务器响应更改页面的一部分。的remote_function ()helper正是这样做的,如清单11-8所示。< / p >清单11-8 -使用remote_function ()助手< / p > < div id =“myzone”> < / div ><?php回声javascript_tag(remote_function(数组(“更新”= >“myzone”,“url”= >“mymodule里/ myaction”,)))? > 请注意< / p >< p >的url参数可以包含内部URI (模块/行动? key1 = value1……)或路由规则名称,就像在regular中一样url_for ().< / p >< / div >< / div >< p >类的响应或请求更新id myzone元素mymodule里/ myaction行动。这种交互称为Ajax,它是高度交互的web应用程序的核心。以下是维基百科(http://en.wikipedia.org/wiki/AJAX< / >)描述它:< / p >< p >一个jax通过在幕后与服务器交换少量数据,使web页面感觉反应更灵敏,这样用户每次更改时就不必重新加载整个web页面。这是为了增加网页的交互性、速度和可用性。< / p >< p >一个jax依赖于XMLHttpRequest这是一个JavaScript对象,它的行为就像一个隐藏的框架,你可以从服务器请求更新它,并重用它来操纵网页的其余部分。这个对象是相当低级的,不同的浏览器以不同的方式处理它,因此手动处理Ajax请求通常意味着要编写很长的代码。幸运的是,Prototype封装了处理Ajax所需的所有代码,并提供了一个更简单的Ajax对象,symfony依赖于这个对象。ob娱乐下载这就是为什么在模板中使用Ajax助手后,Prototype库会自动加载。< / p > 谨慎< / p >< p >如果远程操作的URL与当前页面不属于同一个域,Ajax helper将无法工作。此限制是出于安全原因而存在的,并且依赖于无法绕过的浏览器限制。< / p >< / div >< / div >< p >一个jax交互由三部分组成:调用者(链接、按钮、表单、时钟或用户为启动操作而操作的任何控件)、服务器操作和页面中显示操作响应的区域。如果远程操作返回要由客户端javascript函数处理的数据,则可以构建更复杂的交互。ob娱乐下载Symfony提供了多个帮助程序,用于在模板中插入Ajax交互,所有这些都包含单词远程以他们的名义。它们还共享一种通用语法——一个包含所有Ajax参数的关联数组。请注意,Ajax helper输出的是HTML代码,而不是JavaScript。< / p > 侧边栏< / p >Ajax动作呢?< / p >< p >被称为远程函数的操作是常规操作。他们遵循路由,可以确定视图呈现的响应与他们返回,将变量传递给模板,并像其他操作一样更改模型。< / p >< p >但是,当通过Ajax调用时,会返回操作真正的以下呼叫:< / p > isAjax美元=这个美元->getRequest()->isXmlHttpRequest(); ob娱乐下载Symfony知道一个动作是在Ajax上下文中,可以相应地调整响应处理。因此,默认情况下,Ajax操作在开发环境中不包括web调试工具栏。此外,它们跳过了装饰过程(默认情况下,它们的模板不包括在布局中)。如果希望对Ajax视图进行装饰,则需要显式指定has_layout:真模块中的此视图view.yml文件。< / p >< p >还有一点:由于响应性在Ajax交互中至关重要,如果响应不是太复杂,那么避免创建视图,而是直接从操作返回响应可能是个好主意。所以你可以用renderText ()方法来跳过模板并提升Ajax请求。< / p >< / div >< / div >Ajax链接< / > Ajax链接构成了Web 2.0应用程序中可用的Ajax交互的很大一部分。的link_to_remote ()Helper输出一个链接,该链接调用一个远程函数,这并不奇怪。语法与的非常相似link_to ()(除了第二个参数是Ajax选项的关联数组),如清单11-9所示。< / p >清单11-9 - Ajax Linklink_to_remote ()助手< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 在本例中,单击“删除这篇文章”链接将向post /删除后台的动作。服务器返回的响应将出现在元素中id反馈.具体流程如图11-1所示。< / p >图11-1—使用超链接触发远程更新< / p >< p > 可以使用图像而不是字符串来承载链接,使用规则名称而不是内部模块/操作URL,并向<一>标签,如清单11-10所示。< / p >清单11-10 -控件的选项link_to_remote ()助手< / p > < div id =“电子邮件”> < / div ><?php回声link_to_remote(image_tag(“刷新”),数组(“更新”= >“电子邮件”,“url”= >“@list_emails”,),数组(“类”= >“ajax_link”,))? > ajax开发的形式< / > Web表单通常调用另一个操作,但这会导致整个页面被刷新。对应的link_to_function ()对于表单来说,表单提交只使用服务器响应更新页面中的元素。这就是form_remote_tag ()helper的语法如清单11-11所示。< / p >清单11-11 - Ajax表单form_remote_tag ()助手< / p > < div id =“item_list”> < / div ><?php回声form_remote_tag(数组(“更新”= >“item_list”,“url”= >“项目/添加”,))? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?php回声submit_tag(“添加”)? >> < /形式 一个form_remote_tag ()打开一个< >形式,和普通的一样form_tag ()帮手。提交此表单将向项目/添加动作在后台,与项字段作为请求参数。的内容将被替换item_list元素,如图11-2所示。使用正则关闭Ajax表单> < /形式关闭标签。< / p >图11-2 -使用表单触发远程更新< / p >< p > 谨慎< / p >< p >一个jax表单不能是多部分的。这是一个局限XMLHttpRequest对象。这意味着您不能通过Ajax表单处理文件上传。但也有一些变通办法——例如,使用隐藏的iframe而不是XMLHttpRequest.< / p >< / div >< / div >< p >如果希望允许表单在页面模式和Ajax模式下工作,最好的解决方案是将其定义为常规表单,但除了正常的提交按钮外,还提供第二个按钮()以Ajax提交表格。ob娱乐下载Symfony调用此按钮submit_to_remote ().这将帮助您构建优雅地降级的Ajax交互。如清单11-12所示。< / p >清单11-12 -带有常规和Ajax提交的表单< / p > < div id =“item_list”> < / div ><?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?phpif_javascript();? ><?php回声submit_to_remote(“ajax_submit”,“添加到Ajax”,数组(“更新”= >“item_list”,“url”= >“@item_add”,))? ><?phpend_if_javascript();? >< noscript ><?php回声submit_tag(“添加”)? >> < / noscript > < /形式 远程和常规提交标记结合使用的另一个例子是编辑文章的表单。它可以提供一个Ajax预览按钮和一个定期提交的发布按钮。< / p > 请注意< / p >< p >当用户按下Enter键时,使用main中定义的操作提交表单< >形式标签——在本例中是一个常规操作。< / p >< / div >< / div >< p >现代表单不仅可以在提交时做出反应,还可以在用户更新字段值时做出反应。在syob娱乐下载mfony中,使用observe_field ()这是我的帮手。清单11-13显示了使用此帮助器构建建议特性的示例项字段触发Ajax调用,刷新item_suggestion元素。< / p >清单11-13 -当字段值随observe_field () <?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? >< div id =“item_suggestion”> < / div ><?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,))? ><?php回声submit_tag(“添加”)? >> < /形式 中编写的模块/操作@item_being_typed规则将在用户每次更改所观察字段的值(项),甚至无须提交表格。动作就能得到电流项的值。价值请求参数。方法中指定的JavaScript表达式,可以传递所观察字段值以外的值与参数。例如,如果你想让动作得到一个参数参数,写入observe_field ()如清单11-14所示。< / p >列表11-14 -将自己的参数传递给远程操作与选项< / p > <?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,“与”= >"'param=' + value",))? > 注意,这个helper并不输出HTML元素,而是输出作为参数传递的元素的行为。在本章后面,你会看到更多JavaScript helper分配行为的例子。< / p >< p >方法可以观察表单的所有字段observe_form ()Helper,它在每次修改表单字段时调用远程函数。< / p >定期调用远程函数< / > 最后但并非最不重要的是periodically_call_remote ()helper是每隔几秒触发一次的Ajax交互。它不附加到HTML控件,而是作为整个页面的行为透明地在后台运行。这对于跟踪鼠标位置、自动保存大型文本区域的内容等非常有用。清单11-15显示了使用此helper的示例。< / p >清单11-15 -使用periodically_call_remote () < div id =“通知”> < / div ><?php回声periodically_call_remote(数组(“频率”= >60,“更新”= >“通知”,“url”= >“@watch”,“与”= >“参数= +美元\F (mycontent)”,))? > 如果不指定秒数(频率)在两次调用远程函数之间等待,则使用默认值10秒。注意与参数是在JavaScript中求值的,因此您可以在其中使用Prototype函数,例如$ F ()函数。< / p >远程呼叫参数< / > 参数之外,前面几节中描述的所有Ajax helper都可以接受其他参数更新而且url参数。Ajax参数的关联数组可以改变和调整远程调用的行为及其响应的处理。< / p >根据响应状态更新不同的元素< / > 如果远程操作失败,远程助手可以选择更新由成功响应更新的元素之外的另一个元素。为此,只需分割值更新参数转换为关联数组,并为元素设置不同的值,以便在成功而且失败.例如,如果一个页面中有许多Ajax交互和一个错误反馈区域,那么这就非常有用。清单11-16演示了如何处理条件更新。< / p >清单11-16 -处理有条件更新< / p > < div id =“错误”> “反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >数组(“成功”= >“反馈”,“失败”= >“错误”),“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 提示< / p >< p >只有HTTP错误代码(500、404和所有不在2XX范围内的代码)才会触发失败更新,而不是返回操作sfView:错误.因此,如果您想让一个操作返回Ajax失败,它必须调用$ this - > getResponse()——> setStatusCode (404)或类似的。< / p >< / div >< / div >根据位置更新元素< / > 就像update_element_function ()属性,可以指定要更新的元素相对于特定元素位置参数。示例如清单11-17所示。< / p >清单11-17 -使用Position参数更改响应位置< / p > < div id =“反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“位置”= >“后”,))? > 方法之后插入Ajax调用的响应反馈元素;也就是在< div >和< p >.使用此方法,可以执行多个Ajax调用,并查看在更新元素。< / p >< p >的位置参数取值为:< / p >< ul ><李>之前:在元素之前 后:在元素之后 前:在元素内容的顶部 底:在元素内容的底部 根据条件更新元素< / > 远程调用可以接受一个附加参数,以允许用户在实际提交XMLHttpRequest,如清单11-18所示。< / p >清单11-18 -使用Confirm参数在调用远程函数前请求确认< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“确认”= >“你确定吗?”,))? > 当用户单击链接时,会弹出一个显示“Are you sure?”的JavaScript对话框post /删除只有当用户通过单击OK确认他的选择时,action才会被调用。< / p >< p >远程调用还可以通过在浏览器端(JavaScript中)执行的测试来调节,如果您提供条件参数,如清单11-19所示。< / p >清单11-19 -根据客户端测试有条件地调用远程函数< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“条件”= >"$('elementID') == true",))? > 确定Ajax请求方法< / > 默认情况下,Ajax请求是使用POST方法发出的。如果希望进行不修改数据的Ajax调用,或者希望在Ajax调用的结果中显示具有内置验证的表单,则可能需要将Ajax请求方法更改为GET。的方法option改变Ajax请求方法,如清单11-20所示。< / p >清单11-20 -更改Ajax请求方法< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“方法”= >“得到”,))? > 授权脚本执行< / > 如果Ajax调用的响应代码(由服务器发送的代码)插入到更新元素)包含JavaScript,你可能会惊讶地发现这些脚本在默认情况下不执行。这是为了降低远程攻击的风险,并且只允许在开发人员确定响应中的代码是什么时才执行脚本。< / p >< p >方法显式声明在远程响应中执行脚本的能力,原因就在于此脚本选择。清单11-21给出了一个Ajax调用的示例,该Ajax调用声明可以执行来自远程响应的JavaScript。< / p >清单11-21 -授权Ajax响应中的脚本执行< / p > < div id =“反馈”> < / div ><?php//如果post/delete操作的响应包含JavaScript//允许浏览器执行它回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“脚本”= >真正的,))? > 如果远程模板包含Ajax帮助程序(例如remote_function ())时,请注意这些PHP函数会生成JavaScript代码,除非您添加'script' => true选择。< / p > 请注意< / p >< p >即使您为远程响应启用了脚本执行,如果您使用工具检查生成的代码,您实际上也不会在远程代码中看到脚本。脚本将执行,但不会出现在代码中。虽然很奇怪,但这种行为完全正常。< / p >< / div >< / div >创建回调< / > Ajax交互的一个重要缺点是,在要更新的区域实际更新之前,它们对用户是不可见的。这意味着在网络缓慢或服务器故障的情况下,用户可能会认为他们的操作被考虑在内,而实际上它没有被处理。这就是为什么通知用户Ajax交互事件很重要的原因。< / p >< p >默认情况下,每个远程请求都是一个异步进程,在此期间可以触发各种JavaScript回调(用于进度指示器等)。所有回调函数都可以访问请求对象,该对象包含底层对象XMLHttpRequest.回调对应于任何Ajax交互的事件:< / p >< ul ><李>之前:在发起请求之前 后:在请求启动后和加载之前 加载:浏览器加载远程响应时 加载:当浏览器完成加载远程响应时 互动:当用户可以与远程响应交互时,即使它还没有完成加载 成功:当XMLHttpRequestHTTP状态码在2XX范围内 失败:当XMLHttpRequestHTTP状态码不在2XX范围内 404:当请求返回404状态时 完整的:当XMLHttpRequest是否完整(火灾后成功或失败,如果他们在场) 例如,在发起远程调用时显示加载指示器,而在接收到响应时隐藏它,这是非常常见的。要实现这一点,只需添加加载而且完整的参数赋给Ajax调用,如清单11-22所示。< / p >清单11-22 -使用Ajax回调显示和隐藏一个活动指示器< / p > < div id =“反馈”> “指标”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= >“Element.show(“指示器”)”,“完成”= >“Element.hide(“指示器”)”,))? > show和hide方法,以及JavaScript Element对象,是Prototype的其他有用的补充。< / p >创造视觉效果< / > ob娱乐下载Symfony集成了script. aculus .us库的视觉效果,允许您做更多的显示和隐藏< div >网页中的元素。你可以在wiki上找到关于效果语法的很欧宝官网下载app好的文档http://script.aculo.us/< / >.基本上,这个库提供了JavaScript对象和函数来操作DOM,以实现复杂的视觉效果。请参见清单11-23中的一些示例。由于结果是网页中某些区域的视觉动画,建议您自己测试效果,以了解它们的真正功能。us网站提供了一个图库,你可以从中了解动态效果。< / p >清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p > //突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble}) ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >清单11-24 -使用visual_effect ()助手< / p > < div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div') 的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >清单11-25 - Ajax回调中的视觉效果< / p > < div id =“反馈”> “指标”风格=“显示:没有”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= > visual_effect(“出现”,“指标”),“完成”= > visual_effect(“消失”,“指标”).visual_effect(“亮点”,“反馈”),))? > 请注意如何通过在回调中连接它们来组合视觉效果。< / p >JSON< / > JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >清单11-26 - JavaScript JSON对象示例< / p > var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}} 如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >清单11-27 -多个Ajax更新的示例模板< / p > < h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p > 为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p > {"title":"我的基本字母","name":" Brown先生"} 然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >清单11-28 -从远程响应中更新多个元素< / p > <?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? > 的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >清单11-29 -返回JSON头的示例操作< / p > 类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;} HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p > 谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p > 提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
ob娱乐下载Symfony代码性能分析< / >< / p >< / div >< / div > 接受SensioLabs专家的培训(2 - 6天的课程-法语或英语)。< / >< / p >< / div >< / div > ob娱乐下载Symfony的会议< / p > ob娱乐下载SymfonyOnline 2023年6月< / > 2023年6月15日至16日< / div >< / div >< / div > ob娱乐下载SymfonyLive巴黎2023< / > 2023年3月23日至24日< / div >< / div >< / div >< / div >< / div >< / div > 基本JavaScript助手< / >< ul ><李>模板中的JavaScript< / > 更新DOM元素< / > 优雅降级< / > 原型< / > Ajax助手< / >< ul ><李>Ajax链接< / > ajax开发的形式< / > 定期调用远程函数< / > 远程呼叫参数< / >< ul ><李>根据响应状态更新不同的元素< / > 根据位置更新元素< / > 根据条件更新元素< / > 确定Ajax请求方法< / > 授权脚本执行< / > 创建回调< / > 创造视觉效果< / > JSON< / > 使用Ajax执行复杂交互< / >< ul ><李>自动完成< / > 拖放< / > 可排序的列表< / > 就地编辑< / > 总结< / > 客户端交互、复杂的视觉效果和异步通信在Web 2.0应用程序中很常见。所有这些都需要JavaScript,但是手动编写代码通常很麻烦,调试也很耗时。幸运的是,symfony通ob娱乐下载过一组完整的助手自动化了模板中JavaScript的许多常见用法。许多客户端行为甚至不需要一行JavaScript就可以编码。开发人员只需要担心他们想要达到的效果,而symfony将处理复杂的语法和兼容性问题。ob娱乐下载< / p >< p >本章描述symfony提供的方便客户端脚本编写的工具:ob娱乐下载< / p >< ul ><李>基本的JavaScript helper输出符合标准<脚本>标记,以更新文档ob娱乐下载对象模型(DOM)元素或触发带有链接的脚本。 Prototype是一个集成在symfony中的JavaScript库,它通过向JavaScriob娱乐下载pt核心添加新函数和方法来加快客户端脚本开发。 Ajax帮助程序允许用户通过单击链接、提交表单或修改表单元素来更新页面的某些部分。 这些helper的许多选项提供了更大的灵活性和功能,特别是通过使用回调函数。 us是另一个JavaScript库,也集成在symfony中,它添加了动态视觉效果来增强界面和用户体验。ob娱乐下载 JavaScript对象符号(JSON)是用于服务器和客户端脚本之间通信的标准。 在symfony应用程序中,组合了上述所有元素的复杂客户端交互是可能的。ob娱乐下载自动补全、拖放、可排序列表和可编辑文本都可以通过一行PHP实现——调用symfony助手。ob娱乐下载 基本JavaScript助手< / > 由于缺乏跨浏览器兼容性,JavaScript一直被认为在专业的web应用程序中几乎没有实际用途。今天,兼容性问题(大部分)得到了解决,一些健壮的库允许您用JavaScript编写复杂的交互程序,而不需要无数行代码,也不需要花费数小时的调试时间。最流行的改进叫做Ajax,这将在本章后面的“Ajax助手”一节中讨论。< / p >< p >矛盾的是,在本章中您将看到很少的JavaScript代码。这是因为symfony有一种原始ob娱乐下载的客户端脚本编写方法:它将JavaScript行为打包并抽象到helper中,因此您的模板最终根本不显示JavaScript代码。对于开发人员来说,向页面中的元素添加一个行为只需要一行PHP,但是这个助手调用会输出JavaScript代码,检查生成的响应将揭示所有封装的复杂性。helper处理浏览器一致性、复杂的极限情况、可扩展性等等,因此它们所包含的JavaScript代码量可能相当重要。因此,本章将教你如何不使用JavaScript来实现你用JavaScript构建的效果。< / p >< p >类的使用,这里描述的所有帮助程序都可以在模板中使用Javascript辅助组。< / p > <?phpuse_helper(Javascript的)? > 您很快就会了解到,这些帮助程序中有些输出HTML代码,有些输出JavaScript代码。< / p >模板中的JavaScript< / > 在XHTML中,JavaScript代码块必须包含在CDATA声明中。但是需要多个JavaScript代码块的页面很快就会变得冗长乏味。这就是symfony提ob娱乐下载供javascript_tag ()helper,它将字符串转换为xhtml兼容的格式<脚本>标签。清单11-1演示了如何使用这个helper。< / p >清单11-1 -使用javascript_tag ()助手< / p > <?php回声javascript_tag(函数foobar(){…}”)? >=> <脚本类型=“text / javascript”>/ / < ![CDATA[函数foobar(){...}/ /]] >> < /脚本 但是JavaScript最常见的用途(而不是代码块)是在触发特定脚本的超链接中。的link_to_function ()helper正是这样做的,如清单11-2所示。< / p >清单11-2 -通过链接触发JavaScriptlink_to_function ()助手< / p > <?php回声link_to_function(“点击我!”,“警报(“foobar”)”)? >=> “#”onClick =“警报(“foobar”);返回none”;>点击我!< / > 就像link_to ()助手,您可以向<一>标记在第三个参数中。< / p > 请注意< / p >< p >就像link_to ()助手有一个button_to ()兄弟,你可以从一个按钮触发JavaScript (< input type = " button " >),即致电button_to_function ()帮手。如果你喜欢可点击的图片,就打电话link_to_function (image_tag(“模板”),“警报(“foobar”)”).< / p >< / div >< / div >更新DOM元素< / > 动态接口中的一个常见任务是更新页面中的元素。这是您通常编写的如清单11-3所示的内容。< / p >清单11-3 -在JavaScript中更新元素< / p > < div id =“指标”>数据处理开始 . b<?php回声javascript_tag(. getelementbyid (指示器”)。innerHTML = "数据处理完成 .”;“)? > ob娱乐下载Symfony为此目的提供了一个生成JavaScript而不是HTML的帮助器,它被称为update_element_function ().清单11-4展示了它的用法。< / p >清单11-4 -在JavaScript中使用update_element_function ()助手< / p > < div id =“指标”>数据处理开始 . b<?php回声javascript_tag(update_element_function(“指标”,数组(“内容”= >"数据处理完成",)))? > 您可能想知道为什么这个helper特别有用,因为它至少和实际的JavaScript代码一样长。这其实是可读性的问题。例如,您可能希望在元素之前或之后插入内容,删除元素而不只是更新它,甚至根据特定条件什么都不做。在这种情况下,JavaScript代码会变得有些混乱,但是update_element_function ()保持模板的可读性,如清单11-5所示。< / p >清单11-5 -选项update_element_function ()助手< / p > //在'indicator'元素后面插入内容update_element_function(“指标”,数组(“位置”= >“后”,“内容”= >"数据处理完成",));//删除'indicator'前面的元素,并且仅当$condition为真时update_element_function(“指标”,数组(“行动”= >美元的条件?“删除”:“空”,“位置”= >“之前”,)) helper使您的模板比任何JavaScript代码都更容易理解,并且对于类似的行为您有单一的语法。这也是helper名称如此长的原因:它使代码自给自足,不需要额外的注释。< / p >优雅降级< / > 的< noscript >标签允许您指定一些HTML代码,这些代码只在不支持JavaScript的浏览器上显示。ob娱乐下载Symfony用另一种方式工作的帮助器补充了这一点:它限定了一些代码,以便只有真正支持JavaScript的浏览器才能执行它。的if_javascript ()而且end_if_javascript ()helper有助于创建能够优雅降级的应用程序,如清单11-6所示。< / p >清单11-6 -使用if_javascript ()允许优雅降级的助手< / p > <?phpif_javascript();? >你已经启用了JavaScript<?phpend_if_javascript();? > 你不没有启用JavaScript。< / p > < / noscript > 请注意< / p >< p >你不需要包含回声当致电if_javascript ()而且end_if_javascript ()帮手。< / p >< / div >< / div >原型< / > Prototype是一个很棒的JavaScript库,它扩展了客户端脚本语言的可能性,添加了您一直梦想的缺失函数,并提供了操作DOM的新机制。项目网址为http://prototypejs.org/< / >.< / p >< p >原型文件与symfony框架捆绑在一起,可以在每个新的symfonyob娱乐下载项目中访问web /科幻/原型/.这意味着你可以通过在动作中添加以下代码来使用Prototype:< / p > prototypeDir美元= sfConfig::得到(“sf_prototype_web_dir”);这个美元->getResponse()->addJavascript(prototypeDir美元./ js /原型的); 或者把它加到view.yml文件:< / p > 所有:javascript脚本:[%SF_PROTOTYPE_WEB_DIR%/js/prototype] 请注意< / p >< p >由于下一节将介绍的sob娱乐下载ymfony Ajax助手依赖于Prototype,因此只要您使用其中的一个,Prototype库就已经自动包含在内了。这意味着如果您的模板调用一个,您不需要手动将Prototype JavaScript添加到响应中_remote帮手。< / p >< / div >< / div >< p >一旦Prototype库被加载,您就可以利用它添加到JavaScript核心中的所有新函数。这本书的目的不是要描述它们,但是你可以很容易地在网络上找到关于Prototype的好的文档,包括以下网站:欧宝官网下载app< / p >< ul ><李>Particletree:http://particletree.com/features/quick-guide-to-prototype/< / > 塞尔吉奥·佩雷拉:http://www.sergiopereira.com/articles/prototype.js.html< / > Script.aculo.us:http://wiki.script.aculo.us/scriptaculous/show/Prototype< / > Prototype添加到JavaScript的一个函数是美元函数,$ ().基本上,这个函数是一个简单的快捷方式. getelementbyid (),但更强大一点。清单11-7给出了它的使用示例。< / p >清单11-7 -使用$ ()JavaScript中通过ID获取元素的函数< / p > 节点= $(“elementID”);//与node = document.getElementById(“elementID”);//它也可以同时检索多个元素//在这种情况下,结果是一个DOM元素数组Nodes = $(“firstDiv”,“secondDiv”); Prototype还提供了一个JavaScript核心所缺少的函数,该函数返回一个数组,其中包含所有将类作为参数传递的DOM元素:< / p > nodes = document.getElementByClassName(“myclass”); 然而,你很少会使用它,因为Prototype提供了一个更强大的功能,叫做double dollar,$ $ ().这个函数根据CSS选择器返回一个DOM元素数组。所以前面的调用也可以写成这样:< / p > 节点= $$(“.myclass”); 由于CSS选择器的强大功能,您可以比使用XPath表达式更容易地按类、ID、父子关系和上下关系解析DOM。你甚至可以使用一个复杂的选择器来访问这些元素:< / p > 节点= $$('体div#主ul li。最后一个img > span.legend'); Prototype提供的语法增强的最后一个例子是each数组迭代器。除了在JavaScript中定义匿名函数和闭包之外,它还提供了与PHP中相同的简洁。如果您手工编写JavaScript,可能会经常使用它。< / p > var蔬菜=[“胡萝卜”,“莴苣”,“大蒜”];蔬菜。每一个(函数(食物){警报(“我爱”+食物);}); 因为使用Prototype在JavaScript中编程要比手工编写有趣得多,而且它也是symfony的一部分,所以您真的应该花几分钟阅读相关文档。欧宝官网下载appob娱乐下载< / p >Ajax助手< / > 如果您希望更新页面中的元素,而不是使用清单11-5所示的JavaScript,而是使用服务器执行的PHP脚本,该怎么办?这将使您有机会根据服务器响应更改页面的一部分。的remote_function ()helper正是这样做的,如清单11-8所示。< / p >清单11-8 -使用remote_function ()助手< / p > < div id =“myzone”> < / div ><?php回声javascript_tag(remote_function(数组(“更新”= >“myzone”,“url”= >“mymodule里/ myaction”,)))? > 请注意< / p >< p >的url参数可以包含内部URI (模块/行动? key1 = value1……)或路由规则名称,就像在regular中一样url_for ().< / p >< / div >< / div >< p >类的响应或请求更新id myzone元素mymodule里/ myaction行动。这种交互称为Ajax,它是高度交互的web应用程序的核心。以下是维基百科(http://en.wikipedia.org/wiki/AJAX< / >)描述它:< / p >< p >一个jax通过在幕后与服务器交换少量数据,使web页面感觉反应更灵敏,这样用户每次更改时就不必重新加载整个web页面。这是为了增加网页的交互性、速度和可用性。< / p >< p >一个jax依赖于XMLHttpRequest这是一个JavaScript对象,它的行为就像一个隐藏的框架,你可以从服务器请求更新它,并重用它来操纵网页的其余部分。这个对象是相当低级的,不同的浏览器以不同的方式处理它,因此手动处理Ajax请求通常意味着要编写很长的代码。幸运的是,Prototype封装了处理Ajax所需的所有代码,并提供了一个更简单的Ajax对象,symfony依赖于这个对象。ob娱乐下载这就是为什么在模板中使用Ajax助手后,Prototype库会自动加载。< / p > 谨慎< / p >< p >如果远程操作的URL与当前页面不属于同一个域,Ajax helper将无法工作。此限制是出于安全原因而存在的,并且依赖于无法绕过的浏览器限制。< / p >< / div >< / div >< p >一个jax交互由三部分组成:调用者(链接、按钮、表单、时钟或用户为启动操作而操作的任何控件)、服务器操作和页面中显示操作响应的区域。如果远程操作返回要由客户端javascript函数处理的数据,则可以构建更复杂的交互。ob娱乐下载Symfony提供了多个帮助程序,用于在模板中插入Ajax交互,所有这些都包含单词远程以他们的名义。它们还共享一种通用语法——一个包含所有Ajax参数的关联数组。请注意,Ajax helper输出的是HTML代码,而不是JavaScript。< / p > 侧边栏< / p >Ajax动作呢?< / p >< p >被称为远程函数的操作是常规操作。他们遵循路由,可以确定视图呈现的响应与他们返回,将变量传递给模板,并像其他操作一样更改模型。< / p >< p >但是,当通过Ajax调用时,会返回操作真正的以下呼叫:< / p > isAjax美元=这个美元->getRequest()->isXmlHttpRequest(); ob娱乐下载Symfony知道一个动作是在Ajax上下文中,可以相应地调整响应处理。因此,默认情况下,Ajax操作在开发环境中不包括web调试工具栏。此外,它们跳过了装饰过程(默认情况下,它们的模板不包括在布局中)。如果希望对Ajax视图进行装饰,则需要显式指定has_layout:真模块中的此视图view.yml文件。< / p >< p >还有一点:由于响应性在Ajax交互中至关重要,如果响应不是太复杂,那么避免创建视图,而是直接从操作返回响应可能是个好主意。所以你可以用renderText ()方法来跳过模板并提升Ajax请求。< / p >< / div >< / div >Ajax链接< / > Ajax链接构成了Web 2.0应用程序中可用的Ajax交互的很大一部分。的link_to_remote ()Helper输出一个链接,该链接调用一个远程函数,这并不奇怪。语法与的非常相似link_to ()(除了第二个参数是Ajax选项的关联数组),如清单11-9所示。< / p >清单11-9 - Ajax Linklink_to_remote ()助手< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 在本例中,单击“删除这篇文章”链接将向post /删除后台的动作。服务器返回的响应将出现在元素中id反馈.具体流程如图11-1所示。< / p >图11-1—使用超链接触发远程更新< / p >< p > 可以使用图像而不是字符串来承载链接,使用规则名称而不是内部模块/操作URL,并向<一>标签,如清单11-10所示。< / p >清单11-10 -控件的选项link_to_remote ()助手< / p > < div id =“电子邮件”> < / div ><?php回声link_to_remote(image_tag(“刷新”),数组(“更新”= >“电子邮件”,“url”= >“@list_emails”,),数组(“类”= >“ajax_link”,))? > ajax开发的形式< / > Web表单通常调用另一个操作,但这会导致整个页面被刷新。对应的link_to_function ()对于表单来说,表单提交只使用服务器响应更新页面中的元素。这就是form_remote_tag ()helper的语法如清单11-11所示。< / p >清单11-11 - Ajax表单form_remote_tag ()助手< / p > < div id =“item_list”> < / div ><?php回声form_remote_tag(数组(“更新”= >“item_list”,“url”= >“项目/添加”,))? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?php回声submit_tag(“添加”)? >> < /形式 一个form_remote_tag ()打开一个< >形式,和普通的一样form_tag ()帮手。提交此表单将向项目/添加动作在后台,与项字段作为请求参数。的内容将被替换item_list元素,如图11-2所示。使用正则关闭Ajax表单> < /形式关闭标签。< / p >图11-2 -使用表单触发远程更新< / p >< p > 谨慎< / p >< p >一个jax表单不能是多部分的。这是一个局限XMLHttpRequest对象。这意味着您不能通过Ajax表单处理文件上传。但也有一些变通办法——例如,使用隐藏的iframe而不是XMLHttpRequest.< / p >< / div >< / div >< p >如果希望允许表单在页面模式和Ajax模式下工作,最好的解决方案是将其定义为常规表单,但除了正常的提交按钮外,还提供第二个按钮()以Ajax提交表格。ob娱乐下载Symfony调用此按钮submit_to_remote ().这将帮助您构建优雅地降级的Ajax交互。如清单11-12所示。< / p >清单11-12 -带有常规和Ajax提交的表单< / p > < div id =“item_list”> < / div ><?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?phpif_javascript();? ><?php回声submit_to_remote(“ajax_submit”,“添加到Ajax”,数组(“更新”= >“item_list”,“url”= >“@item_add”,))? ><?phpend_if_javascript();? >< noscript ><?php回声submit_tag(“添加”)? >> < / noscript > < /形式 远程和常规提交标记结合使用的另一个例子是编辑文章的表单。它可以提供一个Ajax预览按钮和一个定期提交的发布按钮。< / p > 请注意< / p >< p >当用户按下Enter键时,使用main中定义的操作提交表单< >形式标签——在本例中是一个常规操作。< / p >< / div >< / div >< p >现代表单不仅可以在提交时做出反应,还可以在用户更新字段值时做出反应。在syob娱乐下载mfony中,使用observe_field ()这是我的帮手。清单11-13显示了使用此帮助器构建建议特性的示例项字段触发Ajax调用,刷新item_suggestion元素。< / p >清单11-13 -当字段值随observe_field () <?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? >< div id =“item_suggestion”> < / div ><?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,))? ><?php回声submit_tag(“添加”)? >> < /形式 中编写的模块/操作@item_being_typed规则将在用户每次更改所观察字段的值(项),甚至无须提交表格。动作就能得到电流项的值。价值请求参数。方法中指定的JavaScript表达式,可以传递所观察字段值以外的值与参数。例如,如果你想让动作得到一个参数参数,写入observe_field ()如清单11-14所示。< / p >列表11-14 -将自己的参数传递给远程操作与选项< / p > <?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,“与”= >"'param=' + value",))? > 注意,这个helper并不输出HTML元素,而是输出作为参数传递的元素的行为。在本章后面,你会看到更多JavaScript helper分配行为的例子。< / p >< p >方法可以观察表单的所有字段observe_form ()Helper,它在每次修改表单字段时调用远程函数。< / p >定期调用远程函数< / > 最后但并非最不重要的是periodically_call_remote ()helper是每隔几秒触发一次的Ajax交互。它不附加到HTML控件,而是作为整个页面的行为透明地在后台运行。这对于跟踪鼠标位置、自动保存大型文本区域的内容等非常有用。清单11-15显示了使用此helper的示例。< / p >清单11-15 -使用periodically_call_remote () < div id =“通知”> < / div ><?php回声periodically_call_remote(数组(“频率”= >60,“更新”= >“通知”,“url”= >“@watch”,“与”= >“参数= +美元\F (mycontent)”,))? > 如果不指定秒数(频率)在两次调用远程函数之间等待,则使用默认值10秒。注意与参数是在JavaScript中求值的,因此您可以在其中使用Prototype函数,例如$ F ()函数。< / p >远程呼叫参数< / > 参数之外,前面几节中描述的所有Ajax helper都可以接受其他参数更新而且url参数。Ajax参数的关联数组可以改变和调整远程调用的行为及其响应的处理。< / p >根据响应状态更新不同的元素< / > 如果远程操作失败,远程助手可以选择更新由成功响应更新的元素之外的另一个元素。为此,只需分割值更新参数转换为关联数组,并为元素设置不同的值,以便在成功而且失败.例如,如果一个页面中有许多Ajax交互和一个错误反馈区域,那么这就非常有用。清单11-16演示了如何处理条件更新。< / p >清单11-16 -处理有条件更新< / p > < div id =“错误”> “反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >数组(“成功”= >“反馈”,“失败”= >“错误”),“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 提示< / p >< p >只有HTTP错误代码(500、404和所有不在2XX范围内的代码)才会触发失败更新,而不是返回操作sfView:错误.因此,如果您想让一个操作返回Ajax失败,它必须调用$ this - > getResponse()——> setStatusCode (404)或类似的。< / p >< / div >< / div >根据位置更新元素< / > 就像update_element_function ()属性,可以指定要更新的元素相对于特定元素位置参数。示例如清单11-17所示。< / p >清单11-17 -使用Position参数更改响应位置< / p > < div id =“反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“位置”= >“后”,))? > 方法之后插入Ajax调用的响应反馈元素;也就是在< div >和< p >.使用此方法,可以执行多个Ajax调用,并查看在更新元素。< / p >< p >的位置参数取值为:< / p >< ul ><李>之前:在元素之前 后:在元素之后 前:在元素内容的顶部 底:在元素内容的底部 根据条件更新元素< / > 远程调用可以接受一个附加参数,以允许用户在实际提交XMLHttpRequest,如清单11-18所示。< / p >清单11-18 -使用Confirm参数在调用远程函数前请求确认< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“确认”= >“你确定吗?”,))? > 当用户单击链接时,会弹出一个显示“Are you sure?”的JavaScript对话框post /删除只有当用户通过单击OK确认他的选择时,action才会被调用。< / p >< p >远程调用还可以通过在浏览器端(JavaScript中)执行的测试来调节,如果您提供条件参数,如清单11-19所示。< / p >清单11-19 -根据客户端测试有条件地调用远程函数< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“条件”= >"$('elementID') == true",))? > 确定Ajax请求方法< / > 默认情况下,Ajax请求是使用POST方法发出的。如果希望进行不修改数据的Ajax调用,或者希望在Ajax调用的结果中显示具有内置验证的表单,则可能需要将Ajax请求方法更改为GET。的方法option改变Ajax请求方法,如清单11-20所示。< / p >清单11-20 -更改Ajax请求方法< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“方法”= >“得到”,))? > 授权脚本执行< / > 如果Ajax调用的响应代码(由服务器发送的代码)插入到更新元素)包含JavaScript,你可能会惊讶地发现这些脚本在默认情况下不执行。这是为了降低远程攻击的风险,并且只允许在开发人员确定响应中的代码是什么时才执行脚本。< / p >< p >方法显式声明在远程响应中执行脚本的能力,原因就在于此脚本选择。清单11-21给出了一个Ajax调用的示例,该Ajax调用声明可以执行来自远程响应的JavaScript。< / p >清单11-21 -授权Ajax响应中的脚本执行< / p > < div id =“反馈”> < / div ><?php//如果post/delete操作的响应包含JavaScript//允许浏览器执行它回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“脚本”= >真正的,))? > 如果远程模板包含Ajax帮助程序(例如remote_function ())时,请注意这些PHP函数会生成JavaScript代码,除非您添加'script' => true选择。< / p > 请注意< / p >< p >即使您为远程响应启用了脚本执行,如果您使用工具检查生成的代码,您实际上也不会在远程代码中看到脚本。脚本将执行,但不会出现在代码中。虽然很奇怪,但这种行为完全正常。< / p >< / div >< / div >创建回调< / > Ajax交互的一个重要缺点是,在要更新的区域实际更新之前,它们对用户是不可见的。这意味着在网络缓慢或服务器故障的情况下,用户可能会认为他们的操作被考虑在内,而实际上它没有被处理。这就是为什么通知用户Ajax交互事件很重要的原因。< / p >< p >默认情况下,每个远程请求都是一个异步进程,在此期间可以触发各种JavaScript回调(用于进度指示器等)。所有回调函数都可以访问请求对象,该对象包含底层对象XMLHttpRequest.回调对应于任何Ajax交互的事件:< / p >< ul ><李>之前:在发起请求之前 后:在请求启动后和加载之前 加载:浏览器加载远程响应时 加载:当浏览器完成加载远程响应时 互动:当用户可以与远程响应交互时,即使它还没有完成加载 成功:当XMLHttpRequestHTTP状态码在2XX范围内 失败:当XMLHttpRequestHTTP状态码不在2XX范围内 404:当请求返回404状态时 完整的:当XMLHttpRequest是否完整(火灾后成功或失败,如果他们在场) 例如,在发起远程调用时显示加载指示器,而在接收到响应时隐藏它,这是非常常见的。要实现这一点,只需添加加载而且完整的参数赋给Ajax调用,如清单11-22所示。< / p >清单11-22 -使用Ajax回调显示和隐藏一个活动指示器< / p > < div id =“反馈”> “指标”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= >“Element.show(“指示器”)”,“完成”= >“Element.hide(“指示器”)”,))? > show和hide方法,以及JavaScript Element对象,是Prototype的其他有用的补充。< / p >创造视觉效果< / > ob娱乐下载Symfony集成了script. aculus .us库的视觉效果,允许您做更多的显示和隐藏< div >网页中的元素。你可以在wiki上找到关于效果语法的很欧宝官网下载app好的文档http://script.aculo.us/< / >.基本上,这个库提供了JavaScript对象和函数来操作DOM,以实现复杂的视觉效果。请参见清单11-23中的一些示例。由于结果是网页中某些区域的视觉动画,建议您自己测试效果,以了解它们的真正功能。us网站提供了一个图库,你可以从中了解动态效果。< / p >清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p > //突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble}) ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >清单11-24 -使用visual_effect ()助手< / p > < div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div') 的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >清单11-25 - Ajax回调中的视觉效果< / p > < div id =“反馈”> “指标”风格=“显示:没有”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= > visual_effect(“出现”,“指标”),“完成”= > visual_effect(“消失”,“指标”).visual_effect(“亮点”,“反馈”),))? > 请注意如何通过在回调中连接它们来组合视觉效果。< / p >JSON< / > JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >清单11-26 - JavaScript JSON对象示例< / p > var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}} 如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >清单11-27 -多个Ajax更新的示例模板< / p > < h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p > 为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p > {"title":"我的基本字母","name":" Brown先生"} 然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >清单11-28 -从远程响应中更新多个元素< / p > <?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? > 的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >清单11-29 -返回JSON头的示例操作< / p > 类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;} HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p > 谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p > 提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
接受SensioLabs专家的培训(2 - 6天的课程-法语或英语)。< / >< / p >< / div >< / div > ob娱乐下载Symfony的会议< / p > ob娱乐下载SymfonyOnline 2023年6月< / > 2023年6月15日至16日< / div >< / div >< / div > ob娱乐下载SymfonyLive巴黎2023< / > 2023年3月23日至24日< / div >< / div >< / div >< / div >< / div >< / div > 基本JavaScript助手< / >< ul ><李>模板中的JavaScript< / > 更新DOM元素< / > 优雅降级< / > 原型< / > Ajax助手< / >< ul ><李>Ajax链接< / > ajax开发的形式< / > 定期调用远程函数< / > 远程呼叫参数< / >< ul ><李>根据响应状态更新不同的元素< / > 根据位置更新元素< / > 根据条件更新元素< / > 确定Ajax请求方法< / > 授权脚本执行< / > 创建回调< / > 创造视觉效果< / > JSON< / > 使用Ajax执行复杂交互< / >< ul ><李>自动完成< / > 拖放< / > 可排序的列表< / > 就地编辑< / > 总结< / > 客户端交互、复杂的视觉效果和异步通信在Web 2.0应用程序中很常见。所有这些都需要JavaScript,但是手动编写代码通常很麻烦,调试也很耗时。幸运的是,symfony通ob娱乐下载过一组完整的助手自动化了模板中JavaScript的许多常见用法。许多客户端行为甚至不需要一行JavaScript就可以编码。开发人员只需要担心他们想要达到的效果,而symfony将处理复杂的语法和兼容性问题。ob娱乐下载< / p >< p >本章描述symfony提供的方便客户端脚本编写的工具:ob娱乐下载< / p >< ul ><李>基本的JavaScript helper输出符合标准<脚本>标记,以更新文档ob娱乐下载对象模型(DOM)元素或触发带有链接的脚本。 Prototype是一个集成在symfony中的JavaScript库,它通过向JavaScriob娱乐下载pt核心添加新函数和方法来加快客户端脚本开发。 Ajax帮助程序允许用户通过单击链接、提交表单或修改表单元素来更新页面的某些部分。 这些helper的许多选项提供了更大的灵活性和功能,特别是通过使用回调函数。 us是另一个JavaScript库,也集成在symfony中,它添加了动态视觉效果来增强界面和用户体验。ob娱乐下载 JavaScript对象符号(JSON)是用于服务器和客户端脚本之间通信的标准。 在symfony应用程序中,组合了上述所有元素的复杂客户端交互是可能的。ob娱乐下载自动补全、拖放、可排序列表和可编辑文本都可以通过一行PHP实现——调用symfony助手。ob娱乐下载 基本JavaScript助手< / > 由于缺乏跨浏览器兼容性,JavaScript一直被认为在专业的web应用程序中几乎没有实际用途。今天,兼容性问题(大部分)得到了解决,一些健壮的库允许您用JavaScript编写复杂的交互程序,而不需要无数行代码,也不需要花费数小时的调试时间。最流行的改进叫做Ajax,这将在本章后面的“Ajax助手”一节中讨论。< / p >< p >矛盾的是,在本章中您将看到很少的JavaScript代码。这是因为symfony有一种原始ob娱乐下载的客户端脚本编写方法:它将JavaScript行为打包并抽象到helper中,因此您的模板最终根本不显示JavaScript代码。对于开发人员来说,向页面中的元素添加一个行为只需要一行PHP,但是这个助手调用会输出JavaScript代码,检查生成的响应将揭示所有封装的复杂性。helper处理浏览器一致性、复杂的极限情况、可扩展性等等,因此它们所包含的JavaScript代码量可能相当重要。因此,本章将教你如何不使用JavaScript来实现你用JavaScript构建的效果。< / p >< p >类的使用,这里描述的所有帮助程序都可以在模板中使用Javascript辅助组。< / p > <?phpuse_helper(Javascript的)? > 您很快就会了解到,这些帮助程序中有些输出HTML代码,有些输出JavaScript代码。< / p >模板中的JavaScript< / > 在XHTML中,JavaScript代码块必须包含在CDATA声明中。但是需要多个JavaScript代码块的页面很快就会变得冗长乏味。这就是symfony提ob娱乐下载供javascript_tag ()helper,它将字符串转换为xhtml兼容的格式<脚本>标签。清单11-1演示了如何使用这个helper。< / p >清单11-1 -使用javascript_tag ()助手< / p > <?php回声javascript_tag(函数foobar(){…}”)? >=> <脚本类型=“text / javascript”>/ / < ![CDATA[函数foobar(){...}/ /]] >> < /脚本 但是JavaScript最常见的用途(而不是代码块)是在触发特定脚本的超链接中。的link_to_function ()helper正是这样做的,如清单11-2所示。< / p >清单11-2 -通过链接触发JavaScriptlink_to_function ()助手< / p > <?php回声link_to_function(“点击我!”,“警报(“foobar”)”)? >=> “#”onClick =“警报(“foobar”);返回none”;>点击我!< / > 就像link_to ()助手,您可以向<一>标记在第三个参数中。< / p > 请注意< / p >< p >就像link_to ()助手有一个button_to ()兄弟,你可以从一个按钮触发JavaScript (< input type = " button " >),即致电button_to_function ()帮手。如果你喜欢可点击的图片,就打电话link_to_function (image_tag(“模板”),“警报(“foobar”)”).< / p >< / div >< / div >更新DOM元素< / > 动态接口中的一个常见任务是更新页面中的元素。这是您通常编写的如清单11-3所示的内容。< / p >清单11-3 -在JavaScript中更新元素< / p > < div id =“指标”>数据处理开始 . b<?php回声javascript_tag(. getelementbyid (指示器”)。innerHTML = "数据处理完成 .”;“)? > ob娱乐下载Symfony为此目的提供了一个生成JavaScript而不是HTML的帮助器,它被称为update_element_function ().清单11-4展示了它的用法。< / p >清单11-4 -在JavaScript中使用update_element_function ()助手< / p > < div id =“指标”>数据处理开始 . b<?php回声javascript_tag(update_element_function(“指标”,数组(“内容”= >"数据处理完成",)))? > 您可能想知道为什么这个helper特别有用,因为它至少和实际的JavaScript代码一样长。这其实是可读性的问题。例如,您可能希望在元素之前或之后插入内容,删除元素而不只是更新它,甚至根据特定条件什么都不做。在这种情况下,JavaScript代码会变得有些混乱,但是update_element_function ()保持模板的可读性,如清单11-5所示。< / p >清单11-5 -选项update_element_function ()助手< / p > //在'indicator'元素后面插入内容update_element_function(“指标”,数组(“位置”= >“后”,“内容”= >"数据处理完成",));//删除'indicator'前面的元素,并且仅当$condition为真时update_element_function(“指标”,数组(“行动”= >美元的条件?“删除”:“空”,“位置”= >“之前”,)) helper使您的模板比任何JavaScript代码都更容易理解,并且对于类似的行为您有单一的语法。这也是helper名称如此长的原因:它使代码自给自足,不需要额外的注释。< / p >优雅降级< / > 的< noscript >标签允许您指定一些HTML代码,这些代码只在不支持JavaScript的浏览器上显示。ob娱乐下载Symfony用另一种方式工作的帮助器补充了这一点:它限定了一些代码,以便只有真正支持JavaScript的浏览器才能执行它。的if_javascript ()而且end_if_javascript ()helper有助于创建能够优雅降级的应用程序,如清单11-6所示。< / p >清单11-6 -使用if_javascript ()允许优雅降级的助手< / p > <?phpif_javascript();? >你已经启用了JavaScript<?phpend_if_javascript();? > 你不没有启用JavaScript。< / p > < / noscript > 请注意< / p >< p >你不需要包含回声当致电if_javascript ()而且end_if_javascript ()帮手。< / p >< / div >< / div >原型< / > Prototype是一个很棒的JavaScript库,它扩展了客户端脚本语言的可能性,添加了您一直梦想的缺失函数,并提供了操作DOM的新机制。项目网址为http://prototypejs.org/< / >.< / p >< p >原型文件与symfony框架捆绑在一起,可以在每个新的symfonyob娱乐下载项目中访问web /科幻/原型/.这意味着你可以通过在动作中添加以下代码来使用Prototype:< / p > prototypeDir美元= sfConfig::得到(“sf_prototype_web_dir”);这个美元->getResponse()->addJavascript(prototypeDir美元./ js /原型的); 或者把它加到view.yml文件:< / p > 所有:javascript脚本:[%SF_PROTOTYPE_WEB_DIR%/js/prototype] 请注意< / p >< p >由于下一节将介绍的sob娱乐下载ymfony Ajax助手依赖于Prototype,因此只要您使用其中的一个,Prototype库就已经自动包含在内了。这意味着如果您的模板调用一个,您不需要手动将Prototype JavaScript添加到响应中_remote帮手。< / p >< / div >< / div >< p >一旦Prototype库被加载,您就可以利用它添加到JavaScript核心中的所有新函数。这本书的目的不是要描述它们,但是你可以很容易地在网络上找到关于Prototype的好的文档,包括以下网站:欧宝官网下载app< / p >< ul ><李>Particletree:http://particletree.com/features/quick-guide-to-prototype/< / > 塞尔吉奥·佩雷拉:http://www.sergiopereira.com/articles/prototype.js.html< / > Script.aculo.us:http://wiki.script.aculo.us/scriptaculous/show/Prototype< / > Prototype添加到JavaScript的一个函数是美元函数,$ ().基本上,这个函数是一个简单的快捷方式. getelementbyid (),但更强大一点。清单11-7给出了它的使用示例。< / p >清单11-7 -使用$ ()JavaScript中通过ID获取元素的函数< / p > 节点= $(“elementID”);//与node = document.getElementById(“elementID”);//它也可以同时检索多个元素//在这种情况下,结果是一个DOM元素数组Nodes = $(“firstDiv”,“secondDiv”); Prototype还提供了一个JavaScript核心所缺少的函数,该函数返回一个数组,其中包含所有将类作为参数传递的DOM元素:< / p > nodes = document.getElementByClassName(“myclass”); 然而,你很少会使用它,因为Prototype提供了一个更强大的功能,叫做double dollar,$ $ ().这个函数根据CSS选择器返回一个DOM元素数组。所以前面的调用也可以写成这样:< / p > 节点= $$(“.myclass”); 由于CSS选择器的强大功能,您可以比使用XPath表达式更容易地按类、ID、父子关系和上下关系解析DOM。你甚至可以使用一个复杂的选择器来访问这些元素:< / p > 节点= $$('体div#主ul li。最后一个img > span.legend'); Prototype提供的语法增强的最后一个例子是each数组迭代器。除了在JavaScript中定义匿名函数和闭包之外,它还提供了与PHP中相同的简洁。如果您手工编写JavaScript,可能会经常使用它。< / p > var蔬菜=[“胡萝卜”,“莴苣”,“大蒜”];蔬菜。每一个(函数(食物){警报(“我爱”+食物);}); 因为使用Prototype在JavaScript中编程要比手工编写有趣得多,而且它也是symfony的一部分,所以您真的应该花几分钟阅读相关文档。欧宝官网下载appob娱乐下载< / p >Ajax助手< / > 如果您希望更新页面中的元素,而不是使用清单11-5所示的JavaScript,而是使用服务器执行的PHP脚本,该怎么办?这将使您有机会根据服务器响应更改页面的一部分。的remote_function ()helper正是这样做的,如清单11-8所示。< / p >清单11-8 -使用remote_function ()助手< / p > < div id =“myzone”> < / div ><?php回声javascript_tag(remote_function(数组(“更新”= >“myzone”,“url”= >“mymodule里/ myaction”,)))? > 请注意< / p >< p >的url参数可以包含内部URI (模块/行动? key1 = value1……)或路由规则名称,就像在regular中一样url_for ().< / p >< / div >< / div >< p >类的响应或请求更新id myzone元素mymodule里/ myaction行动。这种交互称为Ajax,它是高度交互的web应用程序的核心。以下是维基百科(http://en.wikipedia.org/wiki/AJAX< / >)描述它:< / p >< p >一个jax通过在幕后与服务器交换少量数据,使web页面感觉反应更灵敏,这样用户每次更改时就不必重新加载整个web页面。这是为了增加网页的交互性、速度和可用性。< / p >< p >一个jax依赖于XMLHttpRequest这是一个JavaScript对象,它的行为就像一个隐藏的框架,你可以从服务器请求更新它,并重用它来操纵网页的其余部分。这个对象是相当低级的,不同的浏览器以不同的方式处理它,因此手动处理Ajax请求通常意味着要编写很长的代码。幸运的是,Prototype封装了处理Ajax所需的所有代码,并提供了一个更简单的Ajax对象,symfony依赖于这个对象。ob娱乐下载这就是为什么在模板中使用Ajax助手后,Prototype库会自动加载。< / p > 谨慎< / p >< p >如果远程操作的URL与当前页面不属于同一个域,Ajax helper将无法工作。此限制是出于安全原因而存在的,并且依赖于无法绕过的浏览器限制。< / p >< / div >< / div >< p >一个jax交互由三部分组成:调用者(链接、按钮、表单、时钟或用户为启动操作而操作的任何控件)、服务器操作和页面中显示操作响应的区域。如果远程操作返回要由客户端javascript函数处理的数据,则可以构建更复杂的交互。ob娱乐下载Symfony提供了多个帮助程序,用于在模板中插入Ajax交互,所有这些都包含单词远程以他们的名义。它们还共享一种通用语法——一个包含所有Ajax参数的关联数组。请注意,Ajax helper输出的是HTML代码,而不是JavaScript。< / p > 侧边栏< / p >Ajax动作呢?< / p >< p >被称为远程函数的操作是常规操作。他们遵循路由,可以确定视图呈现的响应与他们返回,将变量传递给模板,并像其他操作一样更改模型。< / p >< p >但是,当通过Ajax调用时,会返回操作真正的以下呼叫:< / p > isAjax美元=这个美元->getRequest()->isXmlHttpRequest(); ob娱乐下载Symfony知道一个动作是在Ajax上下文中,可以相应地调整响应处理。因此,默认情况下,Ajax操作在开发环境中不包括web调试工具栏。此外,它们跳过了装饰过程(默认情况下,它们的模板不包括在布局中)。如果希望对Ajax视图进行装饰,则需要显式指定has_layout:真模块中的此视图view.yml文件。< / p >< p >还有一点:由于响应性在Ajax交互中至关重要,如果响应不是太复杂,那么避免创建视图,而是直接从操作返回响应可能是个好主意。所以你可以用renderText ()方法来跳过模板并提升Ajax请求。< / p >< / div >< / div >Ajax链接< / > Ajax链接构成了Web 2.0应用程序中可用的Ajax交互的很大一部分。的link_to_remote ()Helper输出一个链接,该链接调用一个远程函数,这并不奇怪。语法与的非常相似link_to ()(除了第二个参数是Ajax选项的关联数组),如清单11-9所示。< / p >清单11-9 - Ajax Linklink_to_remote ()助手< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 在本例中,单击“删除这篇文章”链接将向post /删除后台的动作。服务器返回的响应将出现在元素中id反馈.具体流程如图11-1所示。< / p >图11-1—使用超链接触发远程更新< / p >< p > 可以使用图像而不是字符串来承载链接,使用规则名称而不是内部模块/操作URL,并向<一>标签,如清单11-10所示。< / p >清单11-10 -控件的选项link_to_remote ()助手< / p > < div id =“电子邮件”> < / div ><?php回声link_to_remote(image_tag(“刷新”),数组(“更新”= >“电子邮件”,“url”= >“@list_emails”,),数组(“类”= >“ajax_link”,))? > ajax开发的形式< / > Web表单通常调用另一个操作,但这会导致整个页面被刷新。对应的link_to_function ()对于表单来说,表单提交只使用服务器响应更新页面中的元素。这就是form_remote_tag ()helper的语法如清单11-11所示。< / p >清单11-11 - Ajax表单form_remote_tag ()助手< / p > < div id =“item_list”> < / div ><?php回声form_remote_tag(数组(“更新”= >“item_list”,“url”= >“项目/添加”,))? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?php回声submit_tag(“添加”)? >> < /形式 一个form_remote_tag ()打开一个< >形式,和普通的一样form_tag ()帮手。提交此表单将向项目/添加动作在后台,与项字段作为请求参数。的内容将被替换item_list元素,如图11-2所示。使用正则关闭Ajax表单> < /形式关闭标签。< / p >图11-2 -使用表单触发远程更新< / p >< p > 谨慎< / p >< p >一个jax表单不能是多部分的。这是一个局限XMLHttpRequest对象。这意味着您不能通过Ajax表单处理文件上传。但也有一些变通办法——例如,使用隐藏的iframe而不是XMLHttpRequest.< / p >< / div >< / div >< p >如果希望允许表单在页面模式和Ajax模式下工作,最好的解决方案是将其定义为常规表单,但除了正常的提交按钮外,还提供第二个按钮()以Ajax提交表格。ob娱乐下载Symfony调用此按钮submit_to_remote ().这将帮助您构建优雅地降级的Ajax交互。如清单11-12所示。< / p >清单11-12 -带有常规和Ajax提交的表单< / p > < div id =“item_list”> < / div ><?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?phpif_javascript();? ><?php回声submit_to_remote(“ajax_submit”,“添加到Ajax”,数组(“更新”= >“item_list”,“url”= >“@item_add”,))? ><?phpend_if_javascript();? >< noscript ><?php回声submit_tag(“添加”)? >> < / noscript > < /形式 远程和常规提交标记结合使用的另一个例子是编辑文章的表单。它可以提供一个Ajax预览按钮和一个定期提交的发布按钮。< / p > 请注意< / p >< p >当用户按下Enter键时,使用main中定义的操作提交表单< >形式标签——在本例中是一个常规操作。< / p >< / div >< / div >< p >现代表单不仅可以在提交时做出反应,还可以在用户更新字段值时做出反应。在syob娱乐下载mfony中,使用observe_field ()这是我的帮手。清单11-13显示了使用此帮助器构建建议特性的示例项字段触发Ajax调用,刷新item_suggestion元素。< / p >清单11-13 -当字段值随observe_field () <?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? >< div id =“item_suggestion”> < / div ><?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,))? ><?php回声submit_tag(“添加”)? >> < /形式 中编写的模块/操作@item_being_typed规则将在用户每次更改所观察字段的值(项),甚至无须提交表格。动作就能得到电流项的值。价值请求参数。方法中指定的JavaScript表达式,可以传递所观察字段值以外的值与参数。例如,如果你想让动作得到一个参数参数,写入observe_field ()如清单11-14所示。< / p >列表11-14 -将自己的参数传递给远程操作与选项< / p > <?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,“与”= >"'param=' + value",))? > 注意,这个helper并不输出HTML元素,而是输出作为参数传递的元素的行为。在本章后面,你会看到更多JavaScript helper分配行为的例子。< / p >< p >方法可以观察表单的所有字段observe_form ()Helper,它在每次修改表单字段时调用远程函数。< / p >定期调用远程函数< / > 最后但并非最不重要的是periodically_call_remote ()helper是每隔几秒触发一次的Ajax交互。它不附加到HTML控件,而是作为整个页面的行为透明地在后台运行。这对于跟踪鼠标位置、自动保存大型文本区域的内容等非常有用。清单11-15显示了使用此helper的示例。< / p >清单11-15 -使用periodically_call_remote () < div id =“通知”> < / div ><?php回声periodically_call_remote(数组(“频率”= >60,“更新”= >“通知”,“url”= >“@watch”,“与”= >“参数= +美元\F (mycontent)”,))? > 如果不指定秒数(频率)在两次调用远程函数之间等待,则使用默认值10秒。注意与参数是在JavaScript中求值的,因此您可以在其中使用Prototype函数,例如$ F ()函数。< / p >远程呼叫参数< / > 参数之外,前面几节中描述的所有Ajax helper都可以接受其他参数更新而且url参数。Ajax参数的关联数组可以改变和调整远程调用的行为及其响应的处理。< / p >根据响应状态更新不同的元素< / > 如果远程操作失败,远程助手可以选择更新由成功响应更新的元素之外的另一个元素。为此,只需分割值更新参数转换为关联数组,并为元素设置不同的值,以便在成功而且失败.例如,如果一个页面中有许多Ajax交互和一个错误反馈区域,那么这就非常有用。清单11-16演示了如何处理条件更新。< / p >清单11-16 -处理有条件更新< / p > < div id =“错误”> “反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >数组(“成功”= >“反馈”,“失败”= >“错误”),“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 提示< / p >< p >只有HTTP错误代码(500、404和所有不在2XX范围内的代码)才会触发失败更新,而不是返回操作sfView:错误.因此,如果您想让一个操作返回Ajax失败,它必须调用$ this - > getResponse()——> setStatusCode (404)或类似的。< / p >< / div >< / div >根据位置更新元素< / > 就像update_element_function ()属性,可以指定要更新的元素相对于特定元素位置参数。示例如清单11-17所示。< / p >清单11-17 -使用Position参数更改响应位置< / p > < div id =“反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“位置”= >“后”,))? > 方法之后插入Ajax调用的响应反馈元素;也就是在< div >和< p >.使用此方法,可以执行多个Ajax调用,并查看在更新元素。< / p >< p >的位置参数取值为:< / p >< ul ><李>之前:在元素之前 后:在元素之后 前:在元素内容的顶部 底:在元素内容的底部 根据条件更新元素< / > 远程调用可以接受一个附加参数,以允许用户在实际提交XMLHttpRequest,如清单11-18所示。< / p >清单11-18 -使用Confirm参数在调用远程函数前请求确认< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“确认”= >“你确定吗?”,))? > 当用户单击链接时,会弹出一个显示“Are you sure?”的JavaScript对话框post /删除只有当用户通过单击OK确认他的选择时,action才会被调用。< / p >< p >远程调用还可以通过在浏览器端(JavaScript中)执行的测试来调节,如果您提供条件参数,如清单11-19所示。< / p >清单11-19 -根据客户端测试有条件地调用远程函数< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“条件”= >"$('elementID') == true",))? > 确定Ajax请求方法< / > 默认情况下,Ajax请求是使用POST方法发出的。如果希望进行不修改数据的Ajax调用,或者希望在Ajax调用的结果中显示具有内置验证的表单,则可能需要将Ajax请求方法更改为GET。的方法option改变Ajax请求方法,如清单11-20所示。< / p >清单11-20 -更改Ajax请求方法< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“方法”= >“得到”,))? > 授权脚本执行< / > 如果Ajax调用的响应代码(由服务器发送的代码)插入到更新元素)包含JavaScript,你可能会惊讶地发现这些脚本在默认情况下不执行。这是为了降低远程攻击的风险,并且只允许在开发人员确定响应中的代码是什么时才执行脚本。< / p >< p >方法显式声明在远程响应中执行脚本的能力,原因就在于此脚本选择。清单11-21给出了一个Ajax调用的示例,该Ajax调用声明可以执行来自远程响应的JavaScript。< / p >清单11-21 -授权Ajax响应中的脚本执行< / p > < div id =“反馈”> < / div ><?php//如果post/delete操作的响应包含JavaScript//允许浏览器执行它回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“脚本”= >真正的,))? > 如果远程模板包含Ajax帮助程序(例如remote_function ())时,请注意这些PHP函数会生成JavaScript代码,除非您添加'script' => true选择。< / p > 请注意< / p >< p >即使您为远程响应启用了脚本执行,如果您使用工具检查生成的代码,您实际上也不会在远程代码中看到脚本。脚本将执行,但不会出现在代码中。虽然很奇怪,但这种行为完全正常。< / p >< / div >< / div >创建回调< / > Ajax交互的一个重要缺点是,在要更新的区域实际更新之前,它们对用户是不可见的。这意味着在网络缓慢或服务器故障的情况下,用户可能会认为他们的操作被考虑在内,而实际上它没有被处理。这就是为什么通知用户Ajax交互事件很重要的原因。< / p >< p >默认情况下,每个远程请求都是一个异步进程,在此期间可以触发各种JavaScript回调(用于进度指示器等)。所有回调函数都可以访问请求对象,该对象包含底层对象XMLHttpRequest.回调对应于任何Ajax交互的事件:< / p >< ul ><李>之前:在发起请求之前 后:在请求启动后和加载之前 加载:浏览器加载远程响应时 加载:当浏览器完成加载远程响应时 互动:当用户可以与远程响应交互时,即使它还没有完成加载 成功:当XMLHttpRequestHTTP状态码在2XX范围内 失败:当XMLHttpRequestHTTP状态码不在2XX范围内 404:当请求返回404状态时 完整的:当XMLHttpRequest是否完整(火灾后成功或失败,如果他们在场) 例如,在发起远程调用时显示加载指示器,而在接收到响应时隐藏它,这是非常常见的。要实现这一点,只需添加加载而且完整的参数赋给Ajax调用,如清单11-22所示。< / p >清单11-22 -使用Ajax回调显示和隐藏一个活动指示器< / p > < div id =“反馈”> “指标”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= >“Element.show(“指示器”)”,“完成”= >“Element.hide(“指示器”)”,))? > show和hide方法,以及JavaScript Element对象,是Prototype的其他有用的补充。< / p >创造视觉效果< / > ob娱乐下载Symfony集成了script. aculus .us库的视觉效果,允许您做更多的显示和隐藏< div >网页中的元素。你可以在wiki上找到关于效果语法的很欧宝官网下载app好的文档http://script.aculo.us/< / >.基本上,这个库提供了JavaScript对象和函数来操作DOM,以实现复杂的视觉效果。请参见清单11-23中的一些示例。由于结果是网页中某些区域的视觉动画,建议您自己测试效果,以了解它们的真正功能。us网站提供了一个图库,你可以从中了解动态效果。< / p >清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p > //突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble}) ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >清单11-24 -使用visual_effect ()助手< / p > < div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div') 的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >清单11-25 - Ajax回调中的视觉效果< / p > < div id =“反馈”> “指标”风格=“显示:没有”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= > visual_effect(“出现”,“指标”),“完成”= > visual_effect(“消失”,“指标”).visual_effect(“亮点”,“反馈”),))? > 请注意如何通过在回调中连接它们来组合视觉效果。< / p >JSON< / > JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >清单11-26 - JavaScript JSON对象示例< / p > var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}} 如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >清单11-27 -多个Ajax更新的示例模板< / p > < h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p > 为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p > {"title":"我的基本字母","name":" Brown先生"} 然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >清单11-28 -从远程响应中更新多个元素< / p > <?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? > 的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >清单11-29 -返回JSON头的示例操作< / p > 类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;} HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p > 谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p > 提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
ob娱乐下载Symfony的会议< / p >
客户端交互、复杂的视觉效果和异步通信在Web 2.0应用程序中很常见。所有这些都需要JavaScript,但是手动编写代码通常很麻烦,调试也很耗时。幸运的是,symfony通ob娱乐下载过一组完整的助手自动化了模板中JavaScript的许多常见用法。许多客户端行为甚至不需要一行JavaScript就可以编码。开发人员只需要担心他们想要达到的效果,而symfony将处理复杂的语法和兼容性问题。ob娱乐下载< / p >< p >本章描述symfony提供的方便客户端脚本编写的工具:ob娱乐下载< / p >< ul ><李>基本的JavaScript helper输出符合标准<脚本>标记,以更新文档ob娱乐下载对象模型(DOM)元素或触发带有链接的脚本。
<脚本>
由于缺乏跨浏览器兼容性,JavaScript一直被认为在专业的web应用程序中几乎没有实际用途。今天,兼容性问题(大部分)得到了解决,一些健壮的库允许您用JavaScript编写复杂的交互程序,而不需要无数行代码,也不需要花费数小时的调试时间。最流行的改进叫做Ajax,这将在本章后面的“Ajax助手”一节中讨论。< / p >< p >矛盾的是,在本章中您将看到很少的JavaScript代码。这是因为symfony有一种原始ob娱乐下载的客户端脚本编写方法:它将JavaScript行为打包并抽象到helper中,因此您的模板最终根本不显示JavaScript代码。对于开发人员来说,向页面中的元素添加一个行为只需要一行PHP,但是这个助手调用会输出JavaScript代码,检查生成的响应将揭示所有封装的复杂性。helper处理浏览器一致性、复杂的极限情况、可扩展性等等,因此它们所包含的JavaScript代码量可能相当重要。因此,本章将教你如何不使用JavaScript来实现你用JavaScript构建的效果。< / p >< p >类的使用,这里描述的所有帮助程序都可以在模板中使用Javascript辅助组。< / p >
Javascript
<?phpuse_helper(Javascript的)? >
您很快就会了解到,这些帮助程序中有些输出HTML代码,有些输出JavaScript代码。< / p >
在XHTML中,JavaScript代码块必须包含在CDATA声明中。但是需要多个JavaScript代码块的页面很快就会变得冗长乏味。这就是symfony提ob娱乐下载供javascript_tag ()helper,它将字符串转换为xhtml兼容的格式<脚本>标签。清单11-1演示了如何使用这个helper。< / p >
javascript_tag ()
清单11-1 -使用javascript_tag ()助手< / p >
<?php回声javascript_tag(函数foobar(){…}”)? >=> <脚本类型=“text / javascript”>/ / < ![CDATA[函数foobar(){...}/ /]] >> < /脚本
但是JavaScript最常见的用途(而不是代码块)是在触发特定脚本的超链接中。的link_to_function ()helper正是这样做的,如清单11-2所示。< / p >
link_to_function ()
清单11-2 -通过链接触发JavaScriptlink_to_function ()助手< / p >
<?php回声link_to_function(“点击我!”,“警报(“foobar”)”)? >=> “#”onClick =“警报(“foobar”);返回none”;>点击我!< / >
就像link_to ()助手,您可以向<一>标记在第三个参数中。< / p >
link_to ()
<一>
请注意< / p >< p >就像link_to ()助手有一个button_to ()兄弟,你可以从一个按钮触发JavaScript (< input type = " button " >),即致电button_to_function ()帮手。如果你喜欢可点击的图片,就打电话link_to_function (image_tag(“模板”),“警报(“foobar”)”).< / p >< / div >< / div >
button_to ()
< input type = " button " >
button_to_function ()
link_to_function (image_tag(“模板”),“警报(“foobar”)”)
动态接口中的一个常见任务是更新页面中的元素。这是您通常编写的如清单11-3所示的内容。< / p >
清单11-3 -在JavaScript中更新元素< / p >
< div id =“指标”>数据处理开始
ob娱乐下载Symfony为此目的提供了一个生成JavaScript而不是HTML的帮助器,它被称为update_element_function ().清单11-4展示了它的用法。< / p >
update_element_function ()
清单11-4 -在JavaScript中使用update_element_function ()助手< / p >
您可能想知道为什么这个helper特别有用,因为它至少和实际的JavaScript代码一样长。这其实是可读性的问题。例如,您可能希望在元素之前或之后插入内容,删除元素而不只是更新它,甚至根据特定条件什么都不做。在这种情况下,JavaScript代码会变得有些混乱,但是update_element_function ()保持模板的可读性,如清单11-5所示。< / p >
清单11-5 -选项update_element_function ()助手< / p >
//在'indicator'元素后面插入内容update_element_function(“指标”,数组(“位置”= >“后”,“内容”= >"数据处理完成",));//删除'indicator'前面的元素,并且仅当$condition为真时update_element_function(“指标”,数组(“行动”= >美元的条件?“删除”:“空”,“位置”= >“之前”,))
helper使您的模板比任何JavaScript代码都更容易理解,并且对于类似的行为您有单一的语法。这也是helper名称如此长的原因:它使代码自给自足,不需要额外的注释。< / p >
的< noscript >标签允许您指定一些HTML代码,这些代码只在不支持JavaScript的浏览器上显示。ob娱乐下载Symfony用另一种方式工作的帮助器补充了这一点:它限定了一些代码,以便只有真正支持JavaScript的浏览器才能执行它。的if_javascript ()而且end_if_javascript ()helper有助于创建能够优雅降级的应用程序,如清单11-6所示。< / p >
< noscript >
if_javascript ()
end_if_javascript ()
清单11-6 -使用if_javascript ()允许优雅降级的助手< / p >
<?phpif_javascript();? >你已经启用了JavaScript<?phpend_if_javascript();? > 你不没有启用JavaScript。< / p > < / noscript >
你已经启用了JavaScript<?phpend_if_javascript();? > 你不没有启用JavaScript。< / p > < / noscript >
你不没有启用JavaScript。< / p > < / noscript >
请注意< / p >< p >你不需要包含回声当致电if_javascript ()而且end_if_javascript ()帮手。< / p >< / div >< / div >
回声
Prototype是一个很棒的JavaScript库,它扩展了客户端脚本语言的可能性,添加了您一直梦想的缺失函数,并提供了操作DOM的新机制。项目网址为http://prototypejs.org/< / >.< / p >< p >原型文件与symfony框架捆绑在一起,可以在每个新的symfonyob娱乐下载项目中访问web /科幻/原型/.这意味着你可以通过在动作中添加以下代码来使用Prototype:< / p > prototypeDir美元= sfConfig::得到(“sf_prototype_web_dir”);这个美元->getResponse()->addJavascript(prototypeDir美元./ js /原型的); 或者把它加到view.yml文件:< / p > 所有:javascript脚本:[%SF_PROTOTYPE_WEB_DIR%/js/prototype] 请注意< / p >< p >由于下一节将介绍的sob娱乐下载ymfony Ajax助手依赖于Prototype,因此只要您使用其中的一个,Prototype库就已经自动包含在内了。这意味着如果您的模板调用一个,您不需要手动将Prototype JavaScript添加到响应中_remote帮手。< / p >< / div >< / div >< p >一旦Prototype库被加载,您就可以利用它添加到JavaScript核心中的所有新函数。这本书的目的不是要描述它们,但是你可以很容易地在网络上找到关于Prototype的好的文档,包括以下网站:欧宝官网下载app< / p >< ul ><李>Particletree:http://particletree.com/features/quick-guide-to-prototype/< / > 塞尔吉奥·佩雷拉:http://www.sergiopereira.com/articles/prototype.js.html< / > Script.aculo.us:http://wiki.script.aculo.us/scriptaculous/show/Prototype< / > Prototype添加到JavaScript的一个函数是美元函数,$ ().基本上,这个函数是一个简单的快捷方式. getelementbyid (),但更强大一点。清单11-7给出了它的使用示例。< / p >清单11-7 -使用$ ()JavaScript中通过ID获取元素的函数< / p > 节点= $(“elementID”);//与node = document.getElementById(“elementID”);//它也可以同时检索多个元素//在这种情况下,结果是一个DOM元素数组Nodes = $(“firstDiv”,“secondDiv”); Prototype还提供了一个JavaScript核心所缺少的函数,该函数返回一个数组,其中包含所有将类作为参数传递的DOM元素:< / p > nodes = document.getElementByClassName(“myclass”); 然而,你很少会使用它,因为Prototype提供了一个更强大的功能,叫做double dollar,$ $ ().这个函数根据CSS选择器返回一个DOM元素数组。所以前面的调用也可以写成这样:< / p > 节点= $$(“.myclass”); 由于CSS选择器的强大功能,您可以比使用XPath表达式更容易地按类、ID、父子关系和上下关系解析DOM。你甚至可以使用一个复杂的选择器来访问这些元素:< / p > 节点= $$('体div#主ul li。最后一个img > span.legend'); Prototype提供的语法增强的最后一个例子是each数组迭代器。除了在JavaScript中定义匿名函数和闭包之外,它还提供了与PHP中相同的简洁。如果您手工编写JavaScript,可能会经常使用它。< / p > var蔬菜=[“胡萝卜”,“莴苣”,“大蒜”];蔬菜。每一个(函数(食物){警报(“我爱”+食物);}); 因为使用Prototype在JavaScript中编程要比手工编写有趣得多,而且它也是symfony的一部分,所以您真的应该花几分钟阅读相关文档。欧宝官网下载appob娱乐下载< / p >Ajax助手< / > 如果您希望更新页面中的元素,而不是使用清单11-5所示的JavaScript,而是使用服务器执行的PHP脚本,该怎么办?这将使您有机会根据服务器响应更改页面的一部分。的remote_function ()helper正是这样做的,如清单11-8所示。< / p >清单11-8 -使用remote_function ()助手< / p > < div id =“myzone”> < / div ><?php回声javascript_tag(remote_function(数组(“更新”= >“myzone”,“url”= >“mymodule里/ myaction”,)))? > 请注意< / p >< p >的url参数可以包含内部URI (模块/行动? key1 = value1……)或路由规则名称,就像在regular中一样url_for ().< / p >< / div >< / div >< p >类的响应或请求更新id myzone元素mymodule里/ myaction行动。这种交互称为Ajax,它是高度交互的web应用程序的核心。以下是维基百科(http://en.wikipedia.org/wiki/AJAX< / >)描述它:< / p >< p >一个jax通过在幕后与服务器交换少量数据,使web页面感觉反应更灵敏,这样用户每次更改时就不必重新加载整个web页面。这是为了增加网页的交互性、速度和可用性。< / p >< p >一个jax依赖于XMLHttpRequest这是一个JavaScript对象,它的行为就像一个隐藏的框架,你可以从服务器请求更新它,并重用它来操纵网页的其余部分。这个对象是相当低级的,不同的浏览器以不同的方式处理它,因此手动处理Ajax请求通常意味着要编写很长的代码。幸运的是,Prototype封装了处理Ajax所需的所有代码,并提供了一个更简单的Ajax对象,symfony依赖于这个对象。ob娱乐下载这就是为什么在模板中使用Ajax助手后,Prototype库会自动加载。< / p > 谨慎< / p >< p >如果远程操作的URL与当前页面不属于同一个域,Ajax helper将无法工作。此限制是出于安全原因而存在的,并且依赖于无法绕过的浏览器限制。< / p >< / div >< / div >< p >一个jax交互由三部分组成:调用者(链接、按钮、表单、时钟或用户为启动操作而操作的任何控件)、服务器操作和页面中显示操作响应的区域。如果远程操作返回要由客户端javascript函数处理的数据,则可以构建更复杂的交互。ob娱乐下载Symfony提供了多个帮助程序,用于在模板中插入Ajax交互,所有这些都包含单词远程以他们的名义。它们还共享一种通用语法——一个包含所有Ajax参数的关联数组。请注意,Ajax helper输出的是HTML代码,而不是JavaScript。< / p > 侧边栏< / p >Ajax动作呢?< / p >< p >被称为远程函数的操作是常规操作。他们遵循路由,可以确定视图呈现的响应与他们返回,将变量传递给模板,并像其他操作一样更改模型。< / p >< p >但是,当通过Ajax调用时,会返回操作真正的以下呼叫:< / p > isAjax美元=这个美元->getRequest()->isXmlHttpRequest(); ob娱乐下载Symfony知道一个动作是在Ajax上下文中,可以相应地调整响应处理。因此,默认情况下,Ajax操作在开发环境中不包括web调试工具栏。此外,它们跳过了装饰过程(默认情况下,它们的模板不包括在布局中)。如果希望对Ajax视图进行装饰,则需要显式指定has_layout:真模块中的此视图view.yml文件。< / p >< p >还有一点:由于响应性在Ajax交互中至关重要,如果响应不是太复杂,那么避免创建视图,而是直接从操作返回响应可能是个好主意。所以你可以用renderText ()方法来跳过模板并提升Ajax请求。< / p >< / div >< / div >Ajax链接< / > Ajax链接构成了Web 2.0应用程序中可用的Ajax交互的很大一部分。的link_to_remote ()Helper输出一个链接,该链接调用一个远程函数,这并不奇怪。语法与的非常相似link_to ()(除了第二个参数是Ajax选项的关联数组),如清单11-9所示。< / p >清单11-9 - Ajax Linklink_to_remote ()助手< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 在本例中,单击“删除这篇文章”链接将向post /删除后台的动作。服务器返回的响应将出现在元素中id反馈.具体流程如图11-1所示。< / p >图11-1—使用超链接触发远程更新< / p >< p > 可以使用图像而不是字符串来承载链接,使用规则名称而不是内部模块/操作URL,并向<一>标签,如清单11-10所示。< / p >清单11-10 -控件的选项link_to_remote ()助手< / p > < div id =“电子邮件”> < / div ><?php回声link_to_remote(image_tag(“刷新”),数组(“更新”= >“电子邮件”,“url”= >“@list_emails”,),数组(“类”= >“ajax_link”,))? > ajax开发的形式< / > Web表单通常调用另一个操作,但这会导致整个页面被刷新。对应的link_to_function ()对于表单来说,表单提交只使用服务器响应更新页面中的元素。这就是form_remote_tag ()helper的语法如清单11-11所示。< / p >清单11-11 - Ajax表单form_remote_tag ()助手< / p > < div id =“item_list”> < / div ><?php回声form_remote_tag(数组(“更新”= >“item_list”,“url”= >“项目/添加”,))? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?php回声submit_tag(“添加”)? >> < /形式 一个form_remote_tag ()打开一个< >形式,和普通的一样form_tag ()帮手。提交此表单将向项目/添加动作在后台,与项字段作为请求参数。的内容将被替换item_list元素,如图11-2所示。使用正则关闭Ajax表单> < /形式关闭标签。< / p >图11-2 -使用表单触发远程更新< / p >< p > 谨慎< / p >< p >一个jax表单不能是多部分的。这是一个局限XMLHttpRequest对象。这意味着您不能通过Ajax表单处理文件上传。但也有一些变通办法——例如,使用隐藏的iframe而不是XMLHttpRequest.< / p >< / div >< / div >< p >如果希望允许表单在页面模式和Ajax模式下工作,最好的解决方案是将其定义为常规表单,但除了正常的提交按钮外,还提供第二个按钮()以Ajax提交表格。ob娱乐下载Symfony调用此按钮submit_to_remote ().这将帮助您构建优雅地降级的Ajax交互。如清单11-12所示。< / p >清单11-12 -带有常规和Ajax提交的表单< / p > < div id =“item_list”> < / div ><?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?phpif_javascript();? ><?php回声submit_to_remote(“ajax_submit”,“添加到Ajax”,数组(“更新”= >“item_list”,“url”= >“@item_add”,))? ><?phpend_if_javascript();? >< noscript ><?php回声submit_tag(“添加”)? >> < / noscript > < /形式 远程和常规提交标记结合使用的另一个例子是编辑文章的表单。它可以提供一个Ajax预览按钮和一个定期提交的发布按钮。< / p > 请注意< / p >< p >当用户按下Enter键时,使用main中定义的操作提交表单< >形式标签——在本例中是一个常规操作。< / p >< / div >< / div >< p >现代表单不仅可以在提交时做出反应,还可以在用户更新字段值时做出反应。在syob娱乐下载mfony中,使用observe_field ()这是我的帮手。清单11-13显示了使用此帮助器构建建议特性的示例项字段触发Ajax调用,刷新item_suggestion元素。< / p >清单11-13 -当字段值随observe_field () <?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? >< div id =“item_suggestion”> < / div ><?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,))? ><?php回声submit_tag(“添加”)? >> < /形式 中编写的模块/操作@item_being_typed规则将在用户每次更改所观察字段的值(项),甚至无须提交表格。动作就能得到电流项的值。价值请求参数。方法中指定的JavaScript表达式,可以传递所观察字段值以外的值与参数。例如,如果你想让动作得到一个参数参数,写入observe_field ()如清单11-14所示。< / p >列表11-14 -将自己的参数传递给远程操作与选项< / p > <?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,“与”= >"'param=' + value",))? > 注意,这个helper并不输出HTML元素,而是输出作为参数传递的元素的行为。在本章后面,你会看到更多JavaScript helper分配行为的例子。< / p >< p >方法可以观察表单的所有字段observe_form ()Helper,它在每次修改表单字段时调用远程函数。< / p >定期调用远程函数< / > 最后但并非最不重要的是periodically_call_remote ()helper是每隔几秒触发一次的Ajax交互。它不附加到HTML控件,而是作为整个页面的行为透明地在后台运行。这对于跟踪鼠标位置、自动保存大型文本区域的内容等非常有用。清单11-15显示了使用此helper的示例。< / p >清单11-15 -使用periodically_call_remote () < div id =“通知”> < / div ><?php回声periodically_call_remote(数组(“频率”= >60,“更新”= >“通知”,“url”= >“@watch”,“与”= >“参数= +美元\F (mycontent)”,))? > 如果不指定秒数(频率)在两次调用远程函数之间等待,则使用默认值10秒。注意与参数是在JavaScript中求值的,因此您可以在其中使用Prototype函数,例如$ F ()函数。< / p >远程呼叫参数< / > 参数之外,前面几节中描述的所有Ajax helper都可以接受其他参数更新而且url参数。Ajax参数的关联数组可以改变和调整远程调用的行为及其响应的处理。< / p >根据响应状态更新不同的元素< / > 如果远程操作失败,远程助手可以选择更新由成功响应更新的元素之外的另一个元素。为此,只需分割值更新参数转换为关联数组,并为元素设置不同的值,以便在成功而且失败.例如,如果一个页面中有许多Ajax交互和一个错误反馈区域,那么这就非常有用。清单11-16演示了如何处理条件更新。< / p >清单11-16 -处理有条件更新< / p > < div id =“错误”> “反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >数组(“成功”= >“反馈”,“失败”= >“错误”),“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 提示< / p >< p >只有HTTP错误代码(500、404和所有不在2XX范围内的代码)才会触发失败更新,而不是返回操作sfView:错误.因此,如果您想让一个操作返回Ajax失败,它必须调用$ this - > getResponse()——> setStatusCode (404)或类似的。< / p >< / div >< / div >根据位置更新元素< / > 就像update_element_function ()属性,可以指定要更新的元素相对于特定元素位置参数。示例如清单11-17所示。< / p >清单11-17 -使用Position参数更改响应位置< / p > < div id =“反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“位置”= >“后”,))? > 方法之后插入Ajax调用的响应反馈元素;也就是在< div >和< p >.使用此方法,可以执行多个Ajax调用,并查看在更新元素。< / p >< p >的位置参数取值为:< / p >< ul ><李>之前:在元素之前 后:在元素之后 前:在元素内容的顶部 底:在元素内容的底部 根据条件更新元素< / > 远程调用可以接受一个附加参数,以允许用户在实际提交XMLHttpRequest,如清单11-18所示。< / p >清单11-18 -使用Confirm参数在调用远程函数前请求确认< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“确认”= >“你确定吗?”,))? > 当用户单击链接时,会弹出一个显示“Are you sure?”的JavaScript对话框post /删除只有当用户通过单击OK确认他的选择时,action才会被调用。< / p >< p >远程调用还可以通过在浏览器端(JavaScript中)执行的测试来调节,如果您提供条件参数,如清单11-19所示。< / p >清单11-19 -根据客户端测试有条件地调用远程函数< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“条件”= >"$('elementID') == true",))? > 确定Ajax请求方法< / > 默认情况下,Ajax请求是使用POST方法发出的。如果希望进行不修改数据的Ajax调用,或者希望在Ajax调用的结果中显示具有内置验证的表单,则可能需要将Ajax请求方法更改为GET。的方法option改变Ajax请求方法,如清单11-20所示。< / p >清单11-20 -更改Ajax请求方法< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“方法”= >“得到”,))? > 授权脚本执行< / > 如果Ajax调用的响应代码(由服务器发送的代码)插入到更新元素)包含JavaScript,你可能会惊讶地发现这些脚本在默认情况下不执行。这是为了降低远程攻击的风险,并且只允许在开发人员确定响应中的代码是什么时才执行脚本。< / p >< p >方法显式声明在远程响应中执行脚本的能力,原因就在于此脚本选择。清单11-21给出了一个Ajax调用的示例,该Ajax调用声明可以执行来自远程响应的JavaScript。< / p >清单11-21 -授权Ajax响应中的脚本执行< / p > < div id =“反馈”> < / div ><?php//如果post/delete操作的响应包含JavaScript//允许浏览器执行它回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“脚本”= >真正的,))? > 如果远程模板包含Ajax帮助程序(例如remote_function ())时,请注意这些PHP函数会生成JavaScript代码,除非您添加'script' => true选择。< / p > 请注意< / p >< p >即使您为远程响应启用了脚本执行,如果您使用工具检查生成的代码,您实际上也不会在远程代码中看到脚本。脚本将执行,但不会出现在代码中。虽然很奇怪,但这种行为完全正常。< / p >< / div >< / div >创建回调< / > Ajax交互的一个重要缺点是,在要更新的区域实际更新之前,它们对用户是不可见的。这意味着在网络缓慢或服务器故障的情况下,用户可能会认为他们的操作被考虑在内,而实际上它没有被处理。这就是为什么通知用户Ajax交互事件很重要的原因。< / p >< p >默认情况下,每个远程请求都是一个异步进程,在此期间可以触发各种JavaScript回调(用于进度指示器等)。所有回调函数都可以访问请求对象,该对象包含底层对象XMLHttpRequest.回调对应于任何Ajax交互的事件:< / p >< ul ><李>之前:在发起请求之前 后:在请求启动后和加载之前 加载:浏览器加载远程响应时 加载:当浏览器完成加载远程响应时 互动:当用户可以与远程响应交互时,即使它还没有完成加载 成功:当XMLHttpRequestHTTP状态码在2XX范围内 失败:当XMLHttpRequestHTTP状态码不在2XX范围内 404:当请求返回404状态时 完整的:当XMLHttpRequest是否完整(火灾后成功或失败,如果他们在场) 例如,在发起远程调用时显示加载指示器,而在接收到响应时隐藏它,这是非常常见的。要实现这一点,只需添加加载而且完整的参数赋给Ajax调用,如清单11-22所示。< / p >清单11-22 -使用Ajax回调显示和隐藏一个活动指示器< / p > < div id =“反馈”> “指标”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= >“Element.show(“指示器”)”,“完成”= >“Element.hide(“指示器”)”,))? > show和hide方法,以及JavaScript Element对象,是Prototype的其他有用的补充。< / p >创造视觉效果< / > ob娱乐下载Symfony集成了script. aculus .us库的视觉效果,允许您做更多的显示和隐藏< div >网页中的元素。你可以在wiki上找到关于效果语法的很欧宝官网下载app好的文档http://script.aculo.us/< / >.基本上,这个库提供了JavaScript对象和函数来操作DOM,以实现复杂的视觉效果。请参见清单11-23中的一些示例。由于结果是网页中某些区域的视觉动画,建议您自己测试效果,以了解它们的真正功能。us网站提供了一个图库,你可以从中了解动态效果。< / p >清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p > //突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble}) ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >清单11-24 -使用visual_effect ()助手< / p > < div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div') 的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >清单11-25 - Ajax回调中的视觉效果< / p > < div id =“反馈”> “指标”风格=“显示:没有”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= > visual_effect(“出现”,“指标”),“完成”= > visual_effect(“消失”,“指标”).visual_effect(“亮点”,“反馈”),))? > 请注意如何通过在回调中连接它们来组合视觉效果。< / p >JSON< / > JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >清单11-26 - JavaScript JSON对象示例< / p > var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}} 如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >清单11-27 -多个Ajax更新的示例模板< / p > < h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p > 为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p > {"title":"我的基本字母","name":" Brown先生"} 然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >清单11-28 -从远程响应中更新多个元素< / p > <?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? > 的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >清单11-29 -返回JSON头的示例操作< / p > 类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;} HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p > 谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p > 提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
web /科幻/原型/
prototypeDir美元= sfConfig::得到(“sf_prototype_web_dir”);这个美元->getResponse()->addJavascript(prototypeDir美元./ js /原型的);
或者把它加到view.yml文件:< / p >
view.yml
所有:javascript脚本:[%SF_PROTOTYPE_WEB_DIR%/js/prototype]
请注意< / p >< p >由于下一节将介绍的sob娱乐下载ymfony Ajax助手依赖于Prototype,因此只要您使用其中的一个,Prototype库就已经自动包含在内了。这意味着如果您的模板调用一个,您不需要手动将Prototype JavaScript添加到响应中_remote帮手。< / p >< / div >< / div >< p >一旦Prototype库被加载,您就可以利用它添加到JavaScript核心中的所有新函数。这本书的目的不是要描述它们,但是你可以很容易地在网络上找到关于Prototype的好的文档,包括以下网站:欧宝官网下载app< / p >< ul ><李>Particletree:http://particletree.com/features/quick-guide-to-prototype/< / > 塞尔吉奥·佩雷拉:http://www.sergiopereira.com/articles/prototype.js.html< / > Script.aculo.us:http://wiki.script.aculo.us/scriptaculous/show/Prototype< / > Prototype添加到JavaScript的一个函数是美元函数,$ ().基本上,这个函数是一个简单的快捷方式. getelementbyid (),但更强大一点。清单11-7给出了它的使用示例。< / p >清单11-7 -使用$ ()JavaScript中通过ID获取元素的函数< / p > 节点= $(“elementID”);//与node = document.getElementById(“elementID”);//它也可以同时检索多个元素//在这种情况下,结果是一个DOM元素数组Nodes = $(“firstDiv”,“secondDiv”); Prototype还提供了一个JavaScript核心所缺少的函数,该函数返回一个数组,其中包含所有将类作为参数传递的DOM元素:< / p > nodes = document.getElementByClassName(“myclass”); 然而,你很少会使用它,因为Prototype提供了一个更强大的功能,叫做double dollar,$ $ ().这个函数根据CSS选择器返回一个DOM元素数组。所以前面的调用也可以写成这样:< / p > 节点= $$(“.myclass”); 由于CSS选择器的强大功能,您可以比使用XPath表达式更容易地按类、ID、父子关系和上下关系解析DOM。你甚至可以使用一个复杂的选择器来访问这些元素:< / p > 节点= $$('体div#主ul li。最后一个img > span.legend'); Prototype提供的语法增强的最后一个例子是each数组迭代器。除了在JavaScript中定义匿名函数和闭包之外,它还提供了与PHP中相同的简洁。如果您手工编写JavaScript,可能会经常使用它。< / p > var蔬菜=[“胡萝卜”,“莴苣”,“大蒜”];蔬菜。每一个(函数(食物){警报(“我爱”+食物);}); 因为使用Prototype在JavaScript中编程要比手工编写有趣得多,而且它也是symfony的一部分,所以您真的应该花几分钟阅读相关文档。欧宝官网下载appob娱乐下载< / p >Ajax助手< / > 如果您希望更新页面中的元素,而不是使用清单11-5所示的JavaScript,而是使用服务器执行的PHP脚本,该怎么办?这将使您有机会根据服务器响应更改页面的一部分。的remote_function ()helper正是这样做的,如清单11-8所示。< / p >清单11-8 -使用remote_function ()助手< / p > < div id =“myzone”> < / div ><?php回声javascript_tag(remote_function(数组(“更新”= >“myzone”,“url”= >“mymodule里/ myaction”,)))? > 请注意< / p >< p >的url参数可以包含内部URI (模块/行动? key1 = value1……)或路由规则名称,就像在regular中一样url_for ().< / p >< / div >< / div >< p >类的响应或请求更新id myzone元素mymodule里/ myaction行动。这种交互称为Ajax,它是高度交互的web应用程序的核心。以下是维基百科(http://en.wikipedia.org/wiki/AJAX< / >)描述它:< / p >< p >一个jax通过在幕后与服务器交换少量数据,使web页面感觉反应更灵敏,这样用户每次更改时就不必重新加载整个web页面。这是为了增加网页的交互性、速度和可用性。< / p >< p >一个jax依赖于XMLHttpRequest这是一个JavaScript对象,它的行为就像一个隐藏的框架,你可以从服务器请求更新它,并重用它来操纵网页的其余部分。这个对象是相当低级的,不同的浏览器以不同的方式处理它,因此手动处理Ajax请求通常意味着要编写很长的代码。幸运的是,Prototype封装了处理Ajax所需的所有代码,并提供了一个更简单的Ajax对象,symfony依赖于这个对象。ob娱乐下载这就是为什么在模板中使用Ajax助手后,Prototype库会自动加载。< / p > 谨慎< / p >< p >如果远程操作的URL与当前页面不属于同一个域,Ajax helper将无法工作。此限制是出于安全原因而存在的,并且依赖于无法绕过的浏览器限制。< / p >< / div >< / div >< p >一个jax交互由三部分组成:调用者(链接、按钮、表单、时钟或用户为启动操作而操作的任何控件)、服务器操作和页面中显示操作响应的区域。如果远程操作返回要由客户端javascript函数处理的数据,则可以构建更复杂的交互。ob娱乐下载Symfony提供了多个帮助程序,用于在模板中插入Ajax交互,所有这些都包含单词远程以他们的名义。它们还共享一种通用语法——一个包含所有Ajax参数的关联数组。请注意,Ajax helper输出的是HTML代码,而不是JavaScript。< / p > 侧边栏< / p >Ajax动作呢?< / p >< p >被称为远程函数的操作是常规操作。他们遵循路由,可以确定视图呈现的响应与他们返回,将变量传递给模板,并像其他操作一样更改模型。< / p >< p >但是,当通过Ajax调用时,会返回操作真正的以下呼叫:< / p > isAjax美元=这个美元->getRequest()->isXmlHttpRequest(); ob娱乐下载Symfony知道一个动作是在Ajax上下文中,可以相应地调整响应处理。因此,默认情况下,Ajax操作在开发环境中不包括web调试工具栏。此外,它们跳过了装饰过程(默认情况下,它们的模板不包括在布局中)。如果希望对Ajax视图进行装饰,则需要显式指定has_layout:真模块中的此视图view.yml文件。< / p >< p >还有一点:由于响应性在Ajax交互中至关重要,如果响应不是太复杂,那么避免创建视图,而是直接从操作返回响应可能是个好主意。所以你可以用renderText ()方法来跳过模板并提升Ajax请求。< / p >< / div >< / div >Ajax链接< / > Ajax链接构成了Web 2.0应用程序中可用的Ajax交互的很大一部分。的link_to_remote ()Helper输出一个链接,该链接调用一个远程函数,这并不奇怪。语法与的非常相似link_to ()(除了第二个参数是Ajax选项的关联数组),如清单11-9所示。< / p >清单11-9 - Ajax Linklink_to_remote ()助手< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 在本例中,单击“删除这篇文章”链接将向post /删除后台的动作。服务器返回的响应将出现在元素中id反馈.具体流程如图11-1所示。< / p >图11-1—使用超链接触发远程更新< / p >< p > 可以使用图像而不是字符串来承载链接,使用规则名称而不是内部模块/操作URL,并向<一>标签,如清单11-10所示。< / p >清单11-10 -控件的选项link_to_remote ()助手< / p > < div id =“电子邮件”> < / div ><?php回声link_to_remote(image_tag(“刷新”),数组(“更新”= >“电子邮件”,“url”= >“@list_emails”,),数组(“类”= >“ajax_link”,))? > ajax开发的形式< / > Web表单通常调用另一个操作,但这会导致整个页面被刷新。对应的link_to_function ()对于表单来说,表单提交只使用服务器响应更新页面中的元素。这就是form_remote_tag ()helper的语法如清单11-11所示。< / p >清单11-11 - Ajax表单form_remote_tag ()助手< / p > < div id =“item_list”> < / div ><?php回声form_remote_tag(数组(“更新”= >“item_list”,“url”= >“项目/添加”,))? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?php回声submit_tag(“添加”)? >> < /形式 一个form_remote_tag ()打开一个< >形式,和普通的一样form_tag ()帮手。提交此表单将向项目/添加动作在后台,与项字段作为请求参数。的内容将被替换item_list元素,如图11-2所示。使用正则关闭Ajax表单> < /形式关闭标签。< / p >图11-2 -使用表单触发远程更新< / p >< p > 谨慎< / p >< p >一个jax表单不能是多部分的。这是一个局限XMLHttpRequest对象。这意味着您不能通过Ajax表单处理文件上传。但也有一些变通办法——例如,使用隐藏的iframe而不是XMLHttpRequest.< / p >< / div >< / div >< p >如果希望允许表单在页面模式和Ajax模式下工作,最好的解决方案是将其定义为常规表单,但除了正常的提交按钮外,还提供第二个按钮()以Ajax提交表格。ob娱乐下载Symfony调用此按钮submit_to_remote ().这将帮助您构建优雅地降级的Ajax交互。如清单11-12所示。< / p >清单11-12 -带有常规和Ajax提交的表单< / p > < div id =“item_list”> < / div ><?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?phpif_javascript();? ><?php回声submit_to_remote(“ajax_submit”,“添加到Ajax”,数组(“更新”= >“item_list”,“url”= >“@item_add”,))? ><?phpend_if_javascript();? >< noscript ><?php回声submit_tag(“添加”)? >> < / noscript > < /形式 远程和常规提交标记结合使用的另一个例子是编辑文章的表单。它可以提供一个Ajax预览按钮和一个定期提交的发布按钮。< / p > 请注意< / p >< p >当用户按下Enter键时,使用main中定义的操作提交表单< >形式标签——在本例中是一个常规操作。< / p >< / div >< / div >< p >现代表单不仅可以在提交时做出反应,还可以在用户更新字段值时做出反应。在syob娱乐下载mfony中,使用observe_field ()这是我的帮手。清单11-13显示了使用此帮助器构建建议特性的示例项字段触发Ajax调用,刷新item_suggestion元素。< / p >清单11-13 -当字段值随observe_field () <?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? >< div id =“item_suggestion”> < / div ><?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,))? ><?php回声submit_tag(“添加”)? >> < /形式 中编写的模块/操作@item_being_typed规则将在用户每次更改所观察字段的值(项),甚至无须提交表格。动作就能得到电流项的值。价值请求参数。方法中指定的JavaScript表达式,可以传递所观察字段值以外的值与参数。例如,如果你想让动作得到一个参数参数,写入observe_field ()如清单11-14所示。< / p >列表11-14 -将自己的参数传递给远程操作与选项< / p > <?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,“与”= >"'param=' + value",))? > 注意,这个helper并不输出HTML元素,而是输出作为参数传递的元素的行为。在本章后面,你会看到更多JavaScript helper分配行为的例子。< / p >< p >方法可以观察表单的所有字段observe_form ()Helper,它在每次修改表单字段时调用远程函数。< / p >定期调用远程函数< / > 最后但并非最不重要的是periodically_call_remote ()helper是每隔几秒触发一次的Ajax交互。它不附加到HTML控件,而是作为整个页面的行为透明地在后台运行。这对于跟踪鼠标位置、自动保存大型文本区域的内容等非常有用。清单11-15显示了使用此helper的示例。< / p >清单11-15 -使用periodically_call_remote () < div id =“通知”> < / div ><?php回声periodically_call_remote(数组(“频率”= >60,“更新”= >“通知”,“url”= >“@watch”,“与”= >“参数= +美元\F (mycontent)”,))? > 如果不指定秒数(频率)在两次调用远程函数之间等待,则使用默认值10秒。注意与参数是在JavaScript中求值的,因此您可以在其中使用Prototype函数,例如$ F ()函数。< / p >远程呼叫参数< / > 参数之外,前面几节中描述的所有Ajax helper都可以接受其他参数更新而且url参数。Ajax参数的关联数组可以改变和调整远程调用的行为及其响应的处理。< / p >根据响应状态更新不同的元素< / > 如果远程操作失败,远程助手可以选择更新由成功响应更新的元素之外的另一个元素。为此,只需分割值更新参数转换为关联数组,并为元素设置不同的值,以便在成功而且失败.例如,如果一个页面中有许多Ajax交互和一个错误反馈区域,那么这就非常有用。清单11-16演示了如何处理条件更新。< / p >清单11-16 -处理有条件更新< / p > < div id =“错误”> “反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >数组(“成功”= >“反馈”,“失败”= >“错误”),“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 提示< / p >< p >只有HTTP错误代码(500、404和所有不在2XX范围内的代码)才会触发失败更新,而不是返回操作sfView:错误.因此,如果您想让一个操作返回Ajax失败,它必须调用$ this - > getResponse()——> setStatusCode (404)或类似的。< / p >< / div >< / div >根据位置更新元素< / > 就像update_element_function ()属性,可以指定要更新的元素相对于特定元素位置参数。示例如清单11-17所示。< / p >清单11-17 -使用Position参数更改响应位置< / p > < div id =“反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“位置”= >“后”,))? > 方法之后插入Ajax调用的响应反馈元素;也就是在< div >和< p >.使用此方法,可以执行多个Ajax调用,并查看在更新元素。< / p >< p >的位置参数取值为:< / p >< ul ><李>之前:在元素之前 后:在元素之后 前:在元素内容的顶部 底:在元素内容的底部 根据条件更新元素< / > 远程调用可以接受一个附加参数,以允许用户在实际提交XMLHttpRequest,如清单11-18所示。< / p >清单11-18 -使用Confirm参数在调用远程函数前请求确认< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“确认”= >“你确定吗?”,))? > 当用户单击链接时,会弹出一个显示“Are you sure?”的JavaScript对话框post /删除只有当用户通过单击OK确认他的选择时,action才会被调用。< / p >< p >远程调用还可以通过在浏览器端(JavaScript中)执行的测试来调节,如果您提供条件参数,如清单11-19所示。< / p >清单11-19 -根据客户端测试有条件地调用远程函数< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“条件”= >"$('elementID') == true",))? > 确定Ajax请求方法< / > 默认情况下,Ajax请求是使用POST方法发出的。如果希望进行不修改数据的Ajax调用,或者希望在Ajax调用的结果中显示具有内置验证的表单,则可能需要将Ajax请求方法更改为GET。的方法option改变Ajax请求方法,如清单11-20所示。< / p >清单11-20 -更改Ajax请求方法< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“方法”= >“得到”,))? > 授权脚本执行< / > 如果Ajax调用的响应代码(由服务器发送的代码)插入到更新元素)包含JavaScript,你可能会惊讶地发现这些脚本在默认情况下不执行。这是为了降低远程攻击的风险,并且只允许在开发人员确定响应中的代码是什么时才执行脚本。< / p >< p >方法显式声明在远程响应中执行脚本的能力,原因就在于此脚本选择。清单11-21给出了一个Ajax调用的示例,该Ajax调用声明可以执行来自远程响应的JavaScript。< / p >清单11-21 -授权Ajax响应中的脚本执行< / p > < div id =“反馈”> < / div ><?php//如果post/delete操作的响应包含JavaScript//允许浏览器执行它回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“脚本”= >真正的,))? > 如果远程模板包含Ajax帮助程序(例如remote_function ())时,请注意这些PHP函数会生成JavaScript代码,除非您添加'script' => true选择。< / p > 请注意< / p >< p >即使您为远程响应启用了脚本执行,如果您使用工具检查生成的代码,您实际上也不会在远程代码中看到脚本。脚本将执行,但不会出现在代码中。虽然很奇怪,但这种行为完全正常。< / p >< / div >< / div >创建回调< / > Ajax交互的一个重要缺点是,在要更新的区域实际更新之前,它们对用户是不可见的。这意味着在网络缓慢或服务器故障的情况下,用户可能会认为他们的操作被考虑在内,而实际上它没有被处理。这就是为什么通知用户Ajax交互事件很重要的原因。< / p >< p >默认情况下,每个远程请求都是一个异步进程,在此期间可以触发各种JavaScript回调(用于进度指示器等)。所有回调函数都可以访问请求对象,该对象包含底层对象XMLHttpRequest.回调对应于任何Ajax交互的事件:< / p >< ul ><李>之前:在发起请求之前 后:在请求启动后和加载之前 加载:浏览器加载远程响应时 加载:当浏览器完成加载远程响应时 互动:当用户可以与远程响应交互时,即使它还没有完成加载 成功:当XMLHttpRequestHTTP状态码在2XX范围内 失败:当XMLHttpRequestHTTP状态码不在2XX范围内 404:当请求返回404状态时 完整的:当XMLHttpRequest是否完整(火灾后成功或失败,如果他们在场) 例如,在发起远程调用时显示加载指示器,而在接收到响应时隐藏它,这是非常常见的。要实现这一点,只需添加加载而且完整的参数赋给Ajax调用,如清单11-22所示。< / p >清单11-22 -使用Ajax回调显示和隐藏一个活动指示器< / p > < div id =“反馈”> “指标”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= >“Element.show(“指示器”)”,“完成”= >“Element.hide(“指示器”)”,))? > show和hide方法,以及JavaScript Element对象,是Prototype的其他有用的补充。< / p >创造视觉效果< / > ob娱乐下载Symfony集成了script. aculus .us库的视觉效果,允许您做更多的显示和隐藏< div >网页中的元素。你可以在wiki上找到关于效果语法的很欧宝官网下载app好的文档http://script.aculo.us/< / >.基本上,这个库提供了JavaScript对象和函数来操作DOM,以实现复杂的视觉效果。请参见清单11-23中的一些示例。由于结果是网页中某些区域的视觉动画,建议您自己测试效果,以了解它们的真正功能。us网站提供了一个图库,你可以从中了解动态效果。< / p >清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p > //突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble}) ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >清单11-24 -使用visual_effect ()助手< / p > < div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div') 的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >清单11-25 - Ajax回调中的视觉效果< / p > < div id =“反馈”> “指标”风格=“显示:没有”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= > visual_effect(“出现”,“指标”),“完成”= > visual_effect(“消失”,“指标”).visual_effect(“亮点”,“反馈”),))? > 请注意如何通过在回调中连接它们来组合视觉效果。< / p >JSON< / > JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >清单11-26 - JavaScript JSON对象示例< / p > var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}} 如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >清单11-27 -多个Ajax更新的示例模板< / p > < h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p > 为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p > {"title":"我的基本字母","name":" Brown先生"} 然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >清单11-28 -从远程响应中更新多个元素< / p > <?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? > 的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >清单11-29 -返回JSON头的示例操作< / p > 类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;} HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p > 谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p > 提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
_remote
Prototype添加到JavaScript的一个函数是美元函数,$ ().基本上,这个函数是一个简单的快捷方式. getelementbyid (),但更强大一点。清单11-7给出了它的使用示例。< / p >
$ ()
. getelementbyid ()
清单11-7 -使用$ ()JavaScript中通过ID获取元素的函数< / p >
节点= $(“elementID”);//与node = document.getElementById(“elementID”);//它也可以同时检索多个元素//在这种情况下,结果是一个DOM元素数组Nodes = $(“firstDiv”,“secondDiv”);
Prototype还提供了一个JavaScript核心所缺少的函数,该函数返回一个数组,其中包含所有将类作为参数传递的DOM元素:< / p >
nodes = document.getElementByClassName(“myclass”);
然而,你很少会使用它,因为Prototype提供了一个更强大的功能,叫做double dollar,$ $ ().这个函数根据CSS选择器返回一个DOM元素数组。所以前面的调用也可以写成这样:< / p >
$ $ ()
节点= $$(“.myclass”);
由于CSS选择器的强大功能,您可以比使用XPath表达式更容易地按类、ID、父子关系和上下关系解析DOM。你甚至可以使用一个复杂的选择器来访问这些元素:< / p >
节点= $$('体div#主ul li。最后一个img > span.legend');
Prototype提供的语法增强的最后一个例子是each数组迭代器。除了在JavaScript中定义匿名函数和闭包之外,它还提供了与PHP中相同的简洁。如果您手工编写JavaScript,可能会经常使用它。< / p >
var蔬菜=[“胡萝卜”,“莴苣”,“大蒜”];蔬菜。每一个(函数(食物){警报(“我爱”+食物);});
因为使用Prototype在JavaScript中编程要比手工编写有趣得多,而且它也是symfony的一部分,所以您真的应该花几分钟阅读相关文档。欧宝官网下载appob娱乐下载< / p >
如果您希望更新页面中的元素,而不是使用清单11-5所示的JavaScript,而是使用服务器执行的PHP脚本,该怎么办?这将使您有机会根据服务器响应更改页面的一部分。的remote_function ()helper正是这样做的,如清单11-8所示。< / p >
remote_function ()
清单11-8 -使用remote_function ()助手< / p >
< div id =“myzone”> < / div ><?php回声javascript_tag(remote_function(数组(“更新”= >“myzone”,“url”= >“mymodule里/ myaction”,)))? >
请注意< / p >< p >的url参数可以包含内部URI (模块/行动? key1 = value1……)或路由规则名称,就像在regular中一样url_for ().< / p >< / div >< / div >< p >类的响应或请求更新id myzone元素mymodule里/ myaction行动。这种交互称为Ajax,它是高度交互的web应用程序的核心。以下是维基百科(http://en.wikipedia.org/wiki/AJAX< / >)描述它:< / p >< p >一个jax通过在幕后与服务器交换少量数据,使web页面感觉反应更灵敏,这样用户每次更改时就不必重新加载整个web页面。这是为了增加网页的交互性、速度和可用性。< / p >< p >一个jax依赖于XMLHttpRequest这是一个JavaScript对象,它的行为就像一个隐藏的框架,你可以从服务器请求更新它,并重用它来操纵网页的其余部分。这个对象是相当低级的,不同的浏览器以不同的方式处理它,因此手动处理Ajax请求通常意味着要编写很长的代码。幸运的是,Prototype封装了处理Ajax所需的所有代码,并提供了一个更简单的Ajax对象,symfony依赖于这个对象。ob娱乐下载这就是为什么在模板中使用Ajax助手后,Prototype库会自动加载。< / p > 谨慎< / p >< p >如果远程操作的URL与当前页面不属于同一个域,Ajax helper将无法工作。此限制是出于安全原因而存在的,并且依赖于无法绕过的浏览器限制。< / p >< / div >< / div >< p >一个jax交互由三部分组成:调用者(链接、按钮、表单、时钟或用户为启动操作而操作的任何控件)、服务器操作和页面中显示操作响应的区域。如果远程操作返回要由客户端javascript函数处理的数据,则可以构建更复杂的交互。ob娱乐下载Symfony提供了多个帮助程序,用于在模板中插入Ajax交互,所有这些都包含单词远程以他们的名义。它们还共享一种通用语法——一个包含所有Ajax参数的关联数组。请注意,Ajax helper输出的是HTML代码,而不是JavaScript。< / p > 侧边栏< / p >Ajax动作呢?< / p >< p >被称为远程函数的操作是常规操作。他们遵循路由,可以确定视图呈现的响应与他们返回,将变量传递给模板,并像其他操作一样更改模型。< / p >< p >但是,当通过Ajax调用时,会返回操作真正的以下呼叫:< / p > isAjax美元=这个美元->getRequest()->isXmlHttpRequest(); ob娱乐下载Symfony知道一个动作是在Ajax上下文中,可以相应地调整响应处理。因此,默认情况下,Ajax操作在开发环境中不包括web调试工具栏。此外,它们跳过了装饰过程(默认情况下,它们的模板不包括在布局中)。如果希望对Ajax视图进行装饰,则需要显式指定has_layout:真模块中的此视图view.yml文件。< / p >< p >还有一点:由于响应性在Ajax交互中至关重要,如果响应不是太复杂,那么避免创建视图,而是直接从操作返回响应可能是个好主意。所以你可以用renderText ()方法来跳过模板并提升Ajax请求。< / p >< / div >< / div >Ajax链接< / > Ajax链接构成了Web 2.0应用程序中可用的Ajax交互的很大一部分。的link_to_remote ()Helper输出一个链接,该链接调用一个远程函数,这并不奇怪。语法与的非常相似link_to ()(除了第二个参数是Ajax选项的关联数组),如清单11-9所示。< / p >清单11-9 - Ajax Linklink_to_remote ()助手< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 在本例中,单击“删除这篇文章”链接将向post /删除后台的动作。服务器返回的响应将出现在元素中id反馈.具体流程如图11-1所示。< / p >图11-1—使用超链接触发远程更新< / p >< p > 可以使用图像而不是字符串来承载链接,使用规则名称而不是内部模块/操作URL,并向<一>标签,如清单11-10所示。< / p >清单11-10 -控件的选项link_to_remote ()助手< / p > < div id =“电子邮件”> < / div ><?php回声link_to_remote(image_tag(“刷新”),数组(“更新”= >“电子邮件”,“url”= >“@list_emails”,),数组(“类”= >“ajax_link”,))? > ajax开发的形式< / > Web表单通常调用另一个操作,但这会导致整个页面被刷新。对应的link_to_function ()对于表单来说,表单提交只使用服务器响应更新页面中的元素。这就是form_remote_tag ()helper的语法如清单11-11所示。< / p >清单11-11 - Ajax表单form_remote_tag ()助手< / p > < div id =“item_list”> < / div ><?php回声form_remote_tag(数组(“更新”= >“item_list”,“url”= >“项目/添加”,))? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?php回声submit_tag(“添加”)? >> < /形式 一个form_remote_tag ()打开一个< >形式,和普通的一样form_tag ()帮手。提交此表单将向项目/添加动作在后台,与项字段作为请求参数。的内容将被替换item_list元素,如图11-2所示。使用正则关闭Ajax表单> < /形式关闭标签。< / p >图11-2 -使用表单触发远程更新< / p >< p > 谨慎< / p >< p >一个jax表单不能是多部分的。这是一个局限XMLHttpRequest对象。这意味着您不能通过Ajax表单处理文件上传。但也有一些变通办法——例如,使用隐藏的iframe而不是XMLHttpRequest.< / p >< / div >< / div >< p >如果希望允许表单在页面模式和Ajax模式下工作,最好的解决方案是将其定义为常规表单,但除了正常的提交按钮外,还提供第二个按钮()以Ajax提交表格。ob娱乐下载Symfony调用此按钮submit_to_remote ().这将帮助您构建优雅地降级的Ajax交互。如清单11-12所示。< / p >清单11-12 -带有常规和Ajax提交的表单< / p > < div id =“item_list”> < / div ><?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?phpif_javascript();? ><?php回声submit_to_remote(“ajax_submit”,“添加到Ajax”,数组(“更新”= >“item_list”,“url”= >“@item_add”,))? ><?phpend_if_javascript();? >< noscript ><?php回声submit_tag(“添加”)? >> < / noscript > < /形式 远程和常规提交标记结合使用的另一个例子是编辑文章的表单。它可以提供一个Ajax预览按钮和一个定期提交的发布按钮。< / p > 请注意< / p >< p >当用户按下Enter键时,使用main中定义的操作提交表单< >形式标签——在本例中是一个常规操作。< / p >< / div >< / div >< p >现代表单不仅可以在提交时做出反应,还可以在用户更新字段值时做出反应。在syob娱乐下载mfony中,使用observe_field ()这是我的帮手。清单11-13显示了使用此帮助器构建建议特性的示例项字段触发Ajax调用,刷新item_suggestion元素。< / p >清单11-13 -当字段值随observe_field () <?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? >< div id =“item_suggestion”> < / div ><?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,))? ><?php回声submit_tag(“添加”)? >> < /形式 中编写的模块/操作@item_being_typed规则将在用户每次更改所观察字段的值(项),甚至无须提交表格。动作就能得到电流项的值。价值请求参数。方法中指定的JavaScript表达式,可以传递所观察字段值以外的值与参数。例如,如果你想让动作得到一个参数参数,写入observe_field ()如清单11-14所示。< / p >列表11-14 -将自己的参数传递给远程操作与选项< / p > <?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,“与”= >"'param=' + value",))? > 注意,这个helper并不输出HTML元素,而是输出作为参数传递的元素的行为。在本章后面,你会看到更多JavaScript helper分配行为的例子。< / p >< p >方法可以观察表单的所有字段observe_form ()Helper,它在每次修改表单字段时调用远程函数。< / p >定期调用远程函数< / > 最后但并非最不重要的是periodically_call_remote ()helper是每隔几秒触发一次的Ajax交互。它不附加到HTML控件,而是作为整个页面的行为透明地在后台运行。这对于跟踪鼠标位置、自动保存大型文本区域的内容等非常有用。清单11-15显示了使用此helper的示例。< / p >清单11-15 -使用periodically_call_remote () < div id =“通知”> < / div ><?php回声periodically_call_remote(数组(“频率”= >60,“更新”= >“通知”,“url”= >“@watch”,“与”= >“参数= +美元\F (mycontent)”,))? > 如果不指定秒数(频率)在两次调用远程函数之间等待,则使用默认值10秒。注意与参数是在JavaScript中求值的,因此您可以在其中使用Prototype函数,例如$ F ()函数。< / p >远程呼叫参数< / > 参数之外,前面几节中描述的所有Ajax helper都可以接受其他参数更新而且url参数。Ajax参数的关联数组可以改变和调整远程调用的行为及其响应的处理。< / p >根据响应状态更新不同的元素< / > 如果远程操作失败,远程助手可以选择更新由成功响应更新的元素之外的另一个元素。为此,只需分割值更新参数转换为关联数组,并为元素设置不同的值,以便在成功而且失败.例如,如果一个页面中有许多Ajax交互和一个错误反馈区域,那么这就非常有用。清单11-16演示了如何处理条件更新。< / p >清单11-16 -处理有条件更新< / p > < div id =“错误”> “反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >数组(“成功”= >“反馈”,“失败”= >“错误”),“url”= >“发布/删除?id = '.美元的帖子->getId(),))? > 提示< / p >< p >只有HTTP错误代码(500、404和所有不在2XX范围内的代码)才会触发失败更新,而不是返回操作sfView:错误.因此,如果您想让一个操作返回Ajax失败,它必须调用$ this - > getResponse()——> setStatusCode (404)或类似的。< / p >< / div >< / div >根据位置更新元素< / > 就像update_element_function ()属性,可以指定要更新的元素相对于特定元素位置参数。示例如清单11-17所示。< / p >清单11-17 -使用Position参数更改响应位置< / p > < div id =“反馈”> Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“位置”= >“后”,))? > 方法之后插入Ajax调用的响应反馈元素;也就是在< div >和< p >.使用此方法,可以执行多个Ajax调用,并查看在更新元素。< / p >< p >的位置参数取值为:< / p >< ul ><李>之前:在元素之前 后:在元素之后 前:在元素内容的顶部 底:在元素内容的底部 根据条件更新元素< / > 远程调用可以接受一个附加参数,以允许用户在实际提交XMLHttpRequest,如清单11-18所示。< / p >清单11-18 -使用Confirm参数在调用远程函数前请求确认< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“确认”= >“你确定吗?”,))? > 当用户单击链接时,会弹出一个显示“Are you sure?”的JavaScript对话框post /删除只有当用户通过单击OK确认他的选择时,action才会被调用。< / p >< p >远程调用还可以通过在浏览器端(JavaScript中)执行的测试来调节,如果您提供条件参数,如清单11-19所示。< / p >清单11-19 -根据客户端测试有条件地调用远程函数< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“条件”= >"$('elementID') == true",))? > 确定Ajax请求方法< / > 默认情况下,Ajax请求是使用POST方法发出的。如果希望进行不修改数据的Ajax调用,或者希望在Ajax调用的结果中显示具有内置验证的表单,则可能需要将Ajax请求方法更改为GET。的方法option改变Ajax请求方法,如清单11-20所示。< / p >清单11-20 -更改Ajax请求方法< / p > < div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“方法”= >“得到”,))? > 授权脚本执行< / > 如果Ajax调用的响应代码(由服务器发送的代码)插入到更新元素)包含JavaScript,你可能会惊讶地发现这些脚本在默认情况下不执行。这是为了降低远程攻击的风险,并且只允许在开发人员确定响应中的代码是什么时才执行脚本。< / p >< p >方法显式声明在远程响应中执行脚本的能力,原因就在于此脚本选择。清单11-21给出了一个Ajax调用的示例,该Ajax调用声明可以执行来自远程响应的JavaScript。< / p >清单11-21 -授权Ajax响应中的脚本执行< / p > < div id =“反馈”> < / div ><?php//如果post/delete操作的响应包含JavaScript//允许浏览器执行它回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“脚本”= >真正的,))? > 如果远程模板包含Ajax帮助程序(例如remote_function ())时,请注意这些PHP函数会生成JavaScript代码,除非您添加'script' => true选择。< / p > 请注意< / p >< p >即使您为远程响应启用了脚本执行,如果您使用工具检查生成的代码,您实际上也不会在远程代码中看到脚本。脚本将执行,但不会出现在代码中。虽然很奇怪,但这种行为完全正常。< / p >< / div >< / div >创建回调< / > Ajax交互的一个重要缺点是,在要更新的区域实际更新之前,它们对用户是不可见的。这意味着在网络缓慢或服务器故障的情况下,用户可能会认为他们的操作被考虑在内,而实际上它没有被处理。这就是为什么通知用户Ajax交互事件很重要的原因。< / p >< p >默认情况下,每个远程请求都是一个异步进程,在此期间可以触发各种JavaScript回调(用于进度指示器等)。所有回调函数都可以访问请求对象,该对象包含底层对象XMLHttpRequest.回调对应于任何Ajax交互的事件:< / p >< ul ><李>之前:在发起请求之前 后:在请求启动后和加载之前 加载:浏览器加载远程响应时 加载:当浏览器完成加载远程响应时 互动:当用户可以与远程响应交互时,即使它还没有完成加载 成功:当XMLHttpRequestHTTP状态码在2XX范围内 失败:当XMLHttpRequestHTTP状态码不在2XX范围内 404:当请求返回404状态时 完整的:当XMLHttpRequest是否完整(火灾后成功或失败,如果他们在场) 例如,在发起远程调用时显示加载指示器,而在接收到响应时隐藏它,这是非常常见的。要实现这一点,只需添加加载而且完整的参数赋给Ajax调用,如清单11-22所示。< / p >清单11-22 -使用Ajax回调显示和隐藏一个活动指示器< / p > < div id =“反馈”> “指标”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= >“Element.show(“指示器”)”,“完成”= >“Element.hide(“指示器”)”,))? > show和hide方法,以及JavaScript Element对象,是Prototype的其他有用的补充。< / p >创造视觉效果< / > ob娱乐下载Symfony集成了script. aculus .us库的视觉效果,允许您做更多的显示和隐藏< div >网页中的元素。你可以在wiki上找到关于效果语法的很欧宝官网下载app好的文档http://script.aculo.us/< / >.基本上,这个库提供了JavaScript对象和函数来操作DOM,以实现复杂的视觉效果。请参见清单11-23中的一些示例。由于结果是网页中某些区域的视觉动画,建议您自己测试效果,以了解它们的真正功能。us网站提供了一个图库,你可以从中了解动态效果。< / p >清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p > //突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble}) ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >清单11-24 -使用visual_effect ()助手< / p > < div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div') 的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >清单11-25 - Ajax回调中的视觉效果< / p > < div id =“反馈”> “指标”风格=“显示:没有”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= > visual_effect(“出现”,“指标”),“完成”= > visual_effect(“消失”,“指标”).visual_effect(“亮点”,“反馈”),))? > 请注意如何通过在回调中连接它们来组合视觉效果。< / p >JSON< / > JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >清单11-26 - JavaScript JSON对象示例< / p > var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}} 如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >清单11-27 -多个Ajax更新的示例模板< / p > < h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p > 为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p > {"title":"我的基本字母","name":" Brown先生"} 然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >清单11-28 -从远程响应中更新多个元素< / p > <?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? > 的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >清单11-29 -返回JSON头的示例操作< / p > 类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;} HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p > 谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p > 提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
url
模块/行动? key1 = value1……
url_for ()
mymodule里/ myaction
XMLHttpRequest
谨慎< / p >< p >如果远程操作的URL与当前页面不属于同一个域,Ajax helper将无法工作。此限制是出于安全原因而存在的,并且依赖于无法绕过的浏览器限制。< / p >< / div >< / div >< p >一个jax交互由三部分组成:调用者(链接、按钮、表单、时钟或用户为启动操作而操作的任何控件)、服务器操作和页面中显示操作响应的区域。如果远程操作返回要由客户端javascript函数处理的数据,则可以构建更复杂的交互。ob娱乐下载Symfony提供了多个帮助程序,用于在模板中插入Ajax交互,所有这些都包含单词远程以他们的名义。它们还共享一种通用语法——一个包含所有Ajax参数的关联数组。请注意,Ajax helper输出的是HTML代码,而不是JavaScript。< / p >
远程
侧边栏< / p >
Ajax动作呢?< / p >< p >被称为远程函数的操作是常规操作。他们遵循路由,可以确定视图呈现的响应与他们返回,将变量传递给模板,并像其他操作一样更改模型。< / p >< p >但是,当通过Ajax调用时,会返回操作真正的以下呼叫:< / p >
返回
真正的
isAjax美元=这个美元->getRequest()->isXmlHttpRequest();
ob娱乐下载Symfony知道一个动作是在Ajax上下文中,可以相应地调整响应处理。因此,默认情况下,Ajax操作在开发环境中不包括web调试工具栏。此外,它们跳过了装饰过程(默认情况下,它们的模板不包括在布局中)。如果希望对Ajax视图进行装饰,则需要显式指定has_layout:真模块中的此视图view.yml文件。< / p >< p >还有一点:由于响应性在Ajax交互中至关重要,如果响应不是太复杂,那么避免创建视图,而是直接从操作返回响应可能是个好主意。所以你可以用renderText ()方法来跳过模板并提升Ajax请求。< / p >< / div >< / div >
has_layout:真
renderText ()
Ajax链接构成了Web 2.0应用程序中可用的Ajax交互的很大一部分。的link_to_remote ()Helper输出一个链接,该链接调用一个远程函数,这并不奇怪。语法与的非常相似link_to ()(除了第二个参数是Ajax选项的关联数组),如清单11-9所示。< / p >
link_to_remote ()
清单11-9 - Ajax Linklink_to_remote ()助手< / p >
< div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),))? >
在本例中,单击“删除这篇文章”链接将向post /删除后台的动作。服务器返回的响应将出现在元素中id反馈.具体流程如图11-1所示。< / p >
“删除这篇文章”
post /删除
id
反馈
图11-1—使用超链接触发远程更新< / p >< p >
可以使用图像而不是字符串来承载链接,使用规则名称而不是内部模块/操作URL,并向<一>标签,如清单11-10所示。< / p >
清单11-10 -控件的选项link_to_remote ()助手< / p >
< div id =“电子邮件”> < / div ><?php回声link_to_remote(image_tag(“刷新”),数组(“更新”= >“电子邮件”,“url”= >“@list_emails”,),数组(“类”= >“ajax_link”,))? >
Web表单通常调用另一个操作,但这会导致整个页面被刷新。对应的link_to_function ()对于表单来说,表单提交只使用服务器响应更新页面中的元素。这就是form_remote_tag ()helper的语法如清单11-11所示。< / p >
form_remote_tag ()
清单11-11 - Ajax表单form_remote_tag ()助手< / p >
< div id =“item_list”> < / div ><?php回声form_remote_tag(数组(“更新”= >“item_list”,“url”= >“项目/添加”,))? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?php回声submit_tag(“添加”)? >> < /形式
一个form_remote_tag ()打开一个< >形式,和普通的一样form_tag ()帮手。提交此表单将向项目/添加动作在后台,与项字段作为请求参数。的内容将被替换item_list元素,如图11-2所示。使用正则关闭Ajax表单> < /形式关闭标签。< / p >
< >形式
form_tag ()
项目/添加
项
item_list
> < /形式
图11-2 -使用表单触发远程更新< / p >< p >
谨慎< / p >< p >一个jax表单不能是多部分的。这是一个局限XMLHttpRequest对象。这意味着您不能通过Ajax表单处理文件上传。但也有一些变通办法——例如,使用隐藏的iframe而不是XMLHttpRequest.< / p >< / div >< / div >< p >如果希望允许表单在页面模式和Ajax模式下工作,最好的解决方案是将其定义为常规表单,但除了正常的提交按钮外,还提供第二个按钮()以Ajax提交表格。ob娱乐下载Symfony调用此按钮submit_to_remote ().这将帮助您构建优雅地降级的Ajax交互。如清单11-12所示。< / p >
iframe
submit_to_remote ()
清单11-12 -带有常规和Ajax提交的表单< / p >
< div id =“item_list”> < / div ><?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? ><?phpif_javascript();? ><?php回声submit_to_remote(“ajax_submit”,“添加到Ajax”,数组(“更新”= >“item_list”,“url”= >“@item_add”,))? ><?phpend_if_javascript();? >< noscript ><?php回声submit_tag(“添加”)? >> < / noscript > < /形式
远程和常规提交标记结合使用的另一个例子是编辑文章的表单。它可以提供一个Ajax预览按钮和一个定期提交的发布按钮。< / p >
请注意< / p >< p >当用户按下Enter键时,使用main中定义的操作提交表单< >形式标签——在本例中是一个常规操作。< / p >< / div >< / div >< p >现代表单不仅可以在提交时做出反应,还可以在用户更新字段值时做出反应。在syob娱乐下载mfony中,使用observe_field ()这是我的帮手。清单11-13显示了使用此帮助器构建建议特性的示例项字段触发Ajax调用,刷新item_suggestion元素。< / p >
observe_field ()
item_suggestion
清单11-13 -当字段值随observe_field ()
<?php回声form_tag(“@item_add_regular”)? ><标签为=“项目”> >项目:< /标签<?php回声input_tag(“项目”)? >< div id =“item_suggestion”> < / div ><?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,))? ><?php回声submit_tag(“添加”)? >> < /形式
中编写的模块/操作@item_being_typed规则将在用户每次更改所观察字段的值(项),甚至无须提交表格。动作就能得到电流项的值。价值请求参数。方法中指定的JavaScript表达式,可以传递所观察字段值以外的值与参数。例如,如果你想让动作得到一个参数参数,写入observe_field ()如清单11-14所示。< / p >
@item_being_typed
价值
与
参数
列表11-14 -将自己的参数传递给远程操作与选项< / p >
<?php回声observe_field(“项目”,数组(“更新”= >“item_suggestion”,“url”= >“@item_being_typed”,“与”= >"'param=' + value",))? >
注意,这个helper并不输出HTML元素,而是输出作为参数传递的元素的行为。在本章后面,你会看到更多JavaScript helper分配行为的例子。< / p >< p >方法可以观察表单的所有字段observe_form ()Helper,它在每次修改表单字段时调用远程函数。< / p >
observe_form ()
最后但并非最不重要的是periodically_call_remote ()helper是每隔几秒触发一次的Ajax交互。它不附加到HTML控件,而是作为整个页面的行为透明地在后台运行。这对于跟踪鼠标位置、自动保存大型文本区域的内容等非常有用。清单11-15显示了使用此helper的示例。< / p >
periodically_call_remote ()
清单11-15 -使用periodically_call_remote ()
< div id =“通知”> < / div ><?php回声periodically_call_remote(数组(“频率”= >60,“更新”= >“通知”,“url”= >“@watch”,“与”= >“参数= +美元\F (mycontent)”,))? >
如果不指定秒数(频率)在两次调用远程函数之间等待,则使用默认值10秒。注意与参数是在JavaScript中求值的,因此您可以在其中使用Prototype函数,例如$ F ()函数。< / p >
频率
$ F ()
参数之外,前面几节中描述的所有Ajax helper都可以接受其他参数更新而且url参数。Ajax参数的关联数组可以改变和调整远程调用的行为及其响应的处理。< / p >
更新
如果远程操作失败,远程助手可以选择更新由成功响应更新的元素之外的另一个元素。为此,只需分割值更新参数转换为关联数组,并为元素设置不同的值,以便在成功而且失败.例如,如果一个页面中有许多Ajax交互和一个错误反馈区域,那么这就非常有用。清单11-16演示了如何处理条件更新。< / p >
成功
失败
清单11-16 -处理有条件更新< / p >
< div id =“错误”>
Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >数组(“成功”= >“反馈”,“失败”= >“错误”),“url”= >“发布/删除?id = '.美元的帖子->getId(),))? >
提示< / p >< p >只有HTTP错误代码(500、404和所有不在2XX范围内的代码)才会触发失败更新,而不是返回操作sfView:错误.因此,如果您想让一个操作返回Ajax失败,它必须调用$ this - > getResponse()——> setStatusCode (404)或类似的。< / p >< / div >< / div >
sfView:错误
$ this - > getResponse()——> setStatusCode (404)
就像update_element_function ()属性,可以指定要更新的元素相对于特定元素位置参数。示例如清单11-17所示。< / p >
位置
清单11-17 -使用Position参数更改响应位置< / p >
< div id =“反馈”>
Hello, World!< / p ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“位置”= >“后”,))? >
方法之后插入Ajax调用的响应反馈元素;也就是在< div >和< p >.使用此方法,可以执行多个Ajax调用,并查看在更新元素。< / p >< p >的位置参数取值为:< / p >< ul ><李>之前:在元素之前
< div >
< p >
之前
后
前
底
远程调用可以接受一个附加参数,以允许用户在实际提交XMLHttpRequest,如清单11-18所示。< / p >
清单11-18 -使用Confirm参数在调用远程函数前请求确认< / p >
< div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“确认”= >“你确定吗?”,))? >
当用户单击链接时,会弹出一个显示“Are you sure?”的JavaScript对话框post /删除只有当用户通过单击OK确认他的选择时,action才会被调用。< / p >< p >远程调用还可以通过在浏览器端(JavaScript中)执行的测试来调节,如果您提供条件参数,如清单11-19所示。< / p >
条件
清单11-19 -根据客户端测试有条件地调用远程函数< / p >
< div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“条件”= >"$('elementID') == true",))? >
默认情况下,Ajax请求是使用POST方法发出的。如果希望进行不修改数据的Ajax调用,或者希望在Ajax调用的结果中显示具有内置验证的表单,则可能需要将Ajax请求方法更改为GET。的方法option改变Ajax请求方法,如清单11-20所示。< / p >
方法
清单11-20 -更改Ajax请求方法< / p >
< div id =“反馈”> < / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“方法”= >“得到”,))? >
如果Ajax调用的响应代码(由服务器发送的代码)插入到更新元素)包含JavaScript,你可能会惊讶地发现这些脚本在默认情况下不执行。这是为了降低远程攻击的风险,并且只允许在开发人员确定响应中的代码是什么时才执行脚本。< / p >< p >方法显式声明在远程响应中执行脚本的能力,原因就在于此脚本选择。清单11-21给出了一个Ajax调用的示例,该Ajax调用声明可以执行来自远程响应的JavaScript。< / p >
脚本
清单11-21 -授权Ajax响应中的脚本执行< / p >
< div id =“反馈”> < / div ><?php//如果post/delete操作的响应包含JavaScript//允许浏览器执行它回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“脚本”= >真正的,))? >
如果远程模板包含Ajax帮助程序(例如remote_function ())时,请注意这些PHP函数会生成JavaScript代码,除非您添加'script' => true选择。< / p >
'script' => true
请注意< / p >< p >即使您为远程响应启用了脚本执行,如果您使用工具检查生成的代码,您实际上也不会在远程代码中看到脚本。脚本将执行,但不会出现在代码中。虽然很奇怪,但这种行为完全正常。< / p >< / div >< / div >
Ajax交互的一个重要缺点是,在要更新的区域实际更新之前,它们对用户是不可见的。这意味着在网络缓慢或服务器故障的情况下,用户可能会认为他们的操作被考虑在内,而实际上它没有被处理。这就是为什么通知用户Ajax交互事件很重要的原因。< / p >< p >默认情况下,每个远程请求都是一个异步进程,在此期间可以触发各种JavaScript回调(用于进度指示器等)。所有回调函数都可以访问请求对象,该对象包含底层对象XMLHttpRequest.回调对应于任何Ajax交互的事件:< / p >< ul ><李>之前:在发起请求之前
请求
加载
互动
404
完整的
例如,在发起远程调用时显示加载指示器,而在接收到响应时隐藏它,这是非常常见的。要实现这一点,只需添加加载而且完整的参数赋给Ajax调用,如清单11-22所示。< / p >
清单11-22 -使用Ajax回调显示和隐藏一个活动指示器< / p >
show和hide方法,以及JavaScript Element对象,是Prototype的其他有用的补充。< / p >
ob娱乐下载Symfony集成了script. aculus .us库的视觉效果,允许您做更多的显示和隐藏< div >网页中的元素。你可以在wiki上找到关于效果语法的很欧宝官网下载app好的文档http://script.aculo.us/< / >.基本上,这个库提供了JavaScript对象和函数来操作DOM,以实现复杂的视觉效果。请参见清单11-23中的一些示例。由于结果是网页中某些区域的视觉动画,建议您自己测试效果,以了解它们的真正功能。us网站提供了一个图库,你可以从中了解动态效果。< / p >清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p > //突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble}) ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >清单11-24 -使用visual_effect ()助手< / p > < div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div') 的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >清单11-25 - Ajax回调中的视觉效果< / p > < div id =“反馈”> “指标”风格=“显示:没有”>加载…< / div ><?php回声link_to_remote(“删除这篇文章”,数组(“更新”= >“反馈”,“url”= >“发布/删除?id = '.美元的帖子->getId(),“加载”= > visual_effect(“出现”,“指标”),“完成”= > visual_effect(“消失”,“指标”).visual_effect(“亮点”,“反馈”),))? > 请注意如何通过在回调中连接它们来组合视觉效果。< / p >JSON< / > JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >清单11-26 - JavaScript JSON对象示例< / p > var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}} 如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >清单11-27 -多个Ajax更新的示例模板< / p > < h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p > 为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p > {"title":"我的基本字母","name":" Brown先生"} 然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >清单11-28 -从远程响应中更新多个元素< / p > <?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? > 的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >清单11-29 -返回JSON头的示例操作< / p > 类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;} HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p > 谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p > 提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
清单11-23 - JavaScript中使用script . aclow .us的视觉效果< / p >
//突出显示元素my_field的效果。突出(“my_field”,{startcolor:“# ff99ff”endcolor:# 999999的})//隐藏一个元素的效果。BlindDown(“id_of_element”);//淡出一个元素的效果。褪色(“id_of_element”,{过渡:Effect.Transitions.wobble})
ob娱乐下载Symfony封装了JavaScript效果对象中调用visual_effect (),仍然是一部分Javascript辅助组。它输出可用于常规链接的JavaScript,如清单11-24所示。< / p >
效果
visual_effect ()
清单11-24 -使用visual_effect ()助手< / p >
< div id =“secret_div”风格=“显示:没有”我一直都在这里!< / div ><?php回声link_to_function(“展示秘密div”, visual_effect(“出现”,“secret_div”))? >//调用Effect.Appear('secret_div')
的visual_effects ()helper也可以在Ajax回调中使用,如清单11-25所示,它显示了与清单11-22类似的活动指示器,但在视觉上更令人满意。的指示器元素在Ajax调用开始时逐渐出现,在响应到达时逐渐消失。此外,在远程调用更新后,反馈元素会突出显示,以吸引用户注意窗口的这一部分。< / p >
visual_effects ()
指示器
清单11-25 - Ajax回调中的视觉效果< / p >
请注意如何通过在回调中连接它们来组合视觉效果。< / p >
JavaScript对象符号(JSON)是一种轻量级的数据交换格式。基本上,它不过是一个JavaScript散列(参见清单11-26中的示例),用于携带对象信息。但是JSON对于Ajax交互有两个很大的好处:它很容易在JavaScript中阅读,并且它可以减少web响应的大小。< / p >
清单11-26 - JavaScript JSON对象示例< / p >
var myJsonData ={"菜单":{" id ":“文件”、“价值”:“文件”、“弹出”:{“菜单项”:[{“价值”:“新”、“onclick”:“CreateNewDoc ()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}}
如果Ajax操作需要将结构化数据返回到调用者页面以进行进一步的JavaScript处理,JSON是响应的一种很好的格式。例如,如果一个Ajax调用要更新调用者页面中的几个元素,这是非常有用的。< / p >< p >例如,假设调用者页面如清单11-27所示。它有两个元素可能需要更新。一个远程助手只能更新页面的一个元素(或元素)标题或者是的名字),但并非两者皆有。< / p >
标题
的名字
清单11-27 -多个Ajax更新的示例模板< / p >
< h1 id =“标题”>基本字母 亲爱的“名称”>name_here, 你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p >
亲爱的“名称”>name_here,
你的e-邮件已收到,稍后回复。真诚< / p > < p >, < / p >
为了更新两者,假设Ajax响应可以是一个包含以下数组的JSON数据块:< / p >
{"title":"我的基本字母","name":" Brown先生"}
然后远程调用可以很容易地解释这个响应,并在JavaScript的帮助下更新一行中的几个字段。清单11-28中的代码显示了可以向清单11-27的模板中添加什么来实现这种效果。< / p >
清单11-28 -从远程响应中更新多个元素< / p >
<?php回声link_to_remote(“刷新字母”,数组(“url”= >“发布/更新”,“完成”= >updateJSON(请求)”))? ><?php回声javascript_tag(" function updateJSON(ajax) {json = ajax. responsejson;var elId;for (elId in json){元素。更新(elId, json (elId));}} ")? >
的完整的callback可以访问Ajax响应并将其传递给第三方函数。这个习俗updateJSON ()函数迭代从响应via获得的JSONresponseJSON对于数组的每个成员,用值的内容更新以键命名的元素。< / p >< p >清单11-29展示了如何发布/更新action可以返回JSON响应。< / p >
updateJSON ()
responseJSON
发布/更新
清单11-29 -返回JSON头的示例操作< / p >
类publishingActions扩展sfActions{公共函数executeRefresh(){输出美元=“[[“标题”、“我的基本信”),(“名字”,“布朗先生”))”;这个美元->getResponse()->setHttpHeader(“X-JSON”,“(”.输出美元.“)”);返回sfView::HEADER_ONLY;}
HTTP协议允许JSON存储在响应报头中。由于响应没有任何内容,因此操作仅将其作为报头立即发送。这完全绕过了视图层,并且速度与- > renderText (),但反应更小。< / p >
- > renderText ()
谨慎< / p >< p >清单11-29所示的方法有一个严重的限制:HTTP报头的最大大小。没有官方的限制,但是浏览器可能不能很好地传输或解释大的头文件。这意味着如果JSON数组很大,远程操作应该返回一个正常的响应,其中JSON是JavaScript数组。< / p >< / div >< / div >< p >JSON已经成为web应用程序的标准。Web服务通常以JSON而不是XML提出响应,以允许在客户端(mashup)而不是在服务器上集成服务。因此,如果您想知道在服务器和JavaScript函数之间使用哪种格式进行通信,JSON可能是最好的选择。< / p >
提示< / p >< p >从5.2版开始,PHP提供了两个函数,json_encode ()而且json_decode (),它允许您在PHP语法和JSON语法之间转换数组,反之亦然(http://www.php.net/manual/en/ref.json.php< / >).这通常有助于JSON数组和Ajax的集成。< / p >< / div >< / div >使用Ajax执行复杂交互< / > 在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p > 谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >自动完成< / > 在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >清单11-30 -响应与Autocomplete标签兼容的示例< / p > advistion1 advistion2 …< / ul > 按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >清单11-31 -在模板中使用自动完成标记帮助器< / p > <?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式 这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >图11-3—自动补全示例< / p >< p > 的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。 频率:周期呼叫的频率,默认为0.4s。 指示器:自动补全建议开始加载时显示的指示器Id,加载完成时消失。 tokens:允许标记化的增量自动补全。例如,如果将此参数设置为,如果用户输入简,乔治,操作将只接收值“乔治”. 拖放< / > 用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p > < ul id =“项目”> “item_1”类=“食物”李胡萝卜> < / ><?php回声draggable_element(“item_1”,数组(“恢复”= >真正的))? ><李id =“item_2”类=“食物”李苹果> < / ><?php回声draggable_element(“item_2”,数组(“恢复”= >真正的))? ><李id =“item_3”类=“食物”李橙色> < / ><?php回声draggable_element(“item_3”,数组(“恢复”= >真正的))? > “购物车”> 您的购物车是空的 拖动这里的项目将它们添加到您的购物车 <?php回声drop_receiving_element(“车”,数组(“url”= >“车/添加”,“接受”= >“食物”,“更新”= >“车”,))? > 无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p > 提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。 重影:克隆元素并拖动克隆元素,保留原元素直到删除克隆元素。 提前:如果设置为假时,不会出现咬断现象。否则,可拖动对象只能拖动到区间x和y的网格的交叉点,在这种情况下,它采用的形式是xy或(x, y)或函数(x,y){返回[x,y]}. 的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。 hoverclass:当用户将一个可接受的可拖拽元素拖到元素上时添加到元素中的CSS类。 可排序的列表< / > 可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >清单11-33 -排序列表示例< / p > < p >做你最喜欢什么? “秩序”> “item_1”类=“合适的”>胡萝卜 “item_2”类=“合适的”>苹果 “item_3”类=“合适的”李>橙子< / >//反正也没人喜欢抱子甘蓝<李id =“item_4”>抱子甘蓝 “反馈”> < / div ><?php回声sortable_element(“秩序”,数组(“url”= >“项目/排序”,“更新”= >“反馈”,“只”= >“合适的”,))? > 通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p > POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_= 完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。 hoverclass:鼠标悬停在元素上时添加到元素中的CSS类。 重叠:设置为水平如果项是内联显示的,则为垂直(默认值)当每行只有一项时(如示例所示)。 标签:如果要排序的列表不是一组<李>元素时,必须定义可排序元素的哪些子元素是可拖动的(例如,div或戴斯。莱纳姆:). 就地编辑< / > 越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >清单11-34 -可编辑文本示例< / p > < div id =“edit_me”你可以编辑这个文本<?php回声input_in_place_editor_tag(“edit_me”,“mymodule里/ myaction”,数组(“关口”= >40,“行”= >10,))? > 当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。 loadTextURL:用来显示要编辑的文本的动作的URI。如果可编辑元素的内容使用特殊格式,并且希望用户在不使用格式的情况下编辑文本,则这很有用。 save_text而且cancel_text:保存链接(默认为“ok”)和取消链接(默认为“cancel”)上的文本。 总结< / > 如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存 本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >
json_encode ()
json_decode ()
在symfony Aob娱乐下载jax帮助程序中,您还会发现一些工具可以通过单个调用构建复杂的交互。它们允许您通过类似桌面应用程序的交互(拖放、自动完成和实时编辑)来增强用户体验,而不需要复杂的JavaScript。下面几节描述了复杂交互的帮助程序,并展示了一些简单的示例。额外的参数和调整在script. acalo .us文档中描述。欧宝官网下载app< / p >
谨慎< / p >< p >如果复杂的交互是可能的,他们需要额外的时间来调整表现,使他们感觉自然。只有当你确信它们能增强用户体验时才使用它们。当它们有可能让用户迷失方向时,要避免使用它们。< / p >< / div >< / div >
在用户输入时显示与用户输入匹配的单词列表的文本输入组件称为自动补全。只有一个帮手input_auto_complete_tag ()如果远程操作返回一个格式为HTML项列表的响应,类似于清单11-30所示的示例,则可以实现此效果。< / p >
input_auto_complete_tag ()
清单11-30 -响应与Autocomplete标签兼容的示例< / p >
按照清单11-31所示的示例,在模板中插入helper,就像使用常规文本输入一样。< / p >
清单11-31 -在模板中使用自动完成标记帮助器< / p >
<?php回声form_tag(“mymodule里/ myaction”)? >根据作者姓名查找:<?php回声input_auto_complete_tag(“作者”,“缺省名称”,作者/自动完成的,数组(“自动完成”= >“关闭”),数组(“use_style”= >真正的))? ><?php回声submit_tag(“发现”)? >> < /形式
这将调用作者/自动完成中输入字符时,执行作者字段。由您来设计操作,以便它根据作者请求参数确定可能匹配的列表,并以类似于清单11-30的格式返回它们。控件下的列表将显示出来作者标签,点击其中一个建议或用键盘选择它将完成输入,如图11-3所示。< / p >
作者/自动完成
作者
图11-3—自动补全示例< / p >< p >
的第三个参数input_auto_complete_tag ()Helper可以接受以下参数:< / p >< ul ><李>use_style:自动设置响应列表的样式。
use_style
,
简,乔治
“乔治”
用鼠标抓取一个元素、移动它并将其释放到其他地方的能力在桌面应用程序中很常见,但在web浏览器中很少见。这是因为用纯JavaScript编写这种行为非常复杂。幸运的是,它只需要symfony中的一行。ob娱乐下载< / p >< p >该框架提供了两个帮助程序,draggable_element ()而且drop_receiving_element (),可视为行为修饰词;它们向所处理的元素添加观察者和能力。使用它们将一个元素声明为可拖拽元素或可拖拽元素的接收元素。可拖动的元素可以通过用鼠标单击来获取。在释放鼠标按钮之前,可以在窗口中移动或拖动元素。接收元素在释放可拖拽元素时调用远程函数。清单11-32演示了这种与购物车接收元素的交互。< / p >
draggable_element ()
drop_receiving_element ()
清单11-32 -购物车中的可拖拽元素和拖放接收元素< / p >
< ul id =“项目”>
您的购物车是空的
拖动这里的项目将它们添加到您的购物车
无序列表中的每一项都可以用鼠标抓取并在窗口中拖动。当被释放时,它们会回到原来的位置。当通过车元素时,它触发对购物车/添加操作的远程调用。操作将能够确定哪个项目被放入车元素id请求参数。因此,清单11-32模拟了一个真实的购物会话:获取商品并将其放入购物车,然后继续结帐。< / p >
车
提示< / p >< p >在清单11-32中,helper被写在它们所修改的元素之后,但这不是必需的。你可以把所有的draggable_element ()而且drop_receiving_element ()模板末尾的helper。重要的是helper调用的第一个参数,它指定接收行为的元素的标识符。< / p >< / div >< / div >< p >的draggable_element ()Helper接受以下参数:< / p >< ul ><李>回复:如果设置为真正的,该元素将在释放时返回到其原始位置。它也可以是任意函数引用,在拖动结束时调用。
回复
重影
提前
假
xy
(x, y)
函数(x,y){返回[x,y]}
的drop_receiving_element ()Helper接受以下参数:< / p >< ul ><李>接受:描述CSS类的字符串或字符串数组。元素将只接受具有一个或多个这样的CSS类的可拖动元素。
接受
hoverclass
可拖拽元素提供的另一种可能性是通过用鼠标移动列表项来对列表进行排序。的sortable_element ()helper将可排序行为添加到项中,清单11-33是实现该特性的一个很好的示例。< / p >
sortable_element ()
清单11-33 -排序列表示例< / p >
< p >做你最喜欢什么?
通过魔法sortable_element ()助手,< ul >元素被设置为可排序的,这意味着它的子元素可以通过拖放来重新排序。每当用户拖动一个项目并释放它以重新排序列表时,就会使用以下参数发出一个Ajax请求:< / p >
< ul >
POST /sf_sandbox/web/frontend_dev.php/item/sort HTTP/1.1 order[]=1&order[]=3&order[]=2&_=
完整的有序列表作为数组传递(格式为订单(排名美元)= $ id,美元的地位从0开始,然后$ id基于下划线(_)在list元素中id属性)。的id可排序元素的属性(订单在本例中)用于命名参数数组。< / p >< p >的sortable_element ()Helper接受以下参数:< / p >< ul ><李>只有:描述CSS类的字符串或字符串数组。只有该类的可排序元素的子元素可以被移动。
订单(排名美元)= $ id
美元的地位
$ id
_
订单
只有
重叠
水平
垂直
标签
<李>
div
戴斯。莱纳姆:
越来越多的web应用程序允许用户直接在页面上编辑页面的内容,而不需要在表单中重新显示内容。交互的原理很简单。当用户将鼠标悬停在文本块上时,该文本块将高亮显示。如果用户在块内单击,则纯文本将转换为填充该块文本的文本区域,并出现一个保存按钮。用户可以编辑文本区域内的文本,一旦保存,文本区域将消失,文本将以普通形式显示。使用symob娱乐下载fony,可以将此可编辑行为添加到元素input_in_place_editor_tag ()帮手。清单11-34演示了如何使用这个helper。< / p >
input_in_place_editor_tag ()
清单11-34 -可编辑文本示例< / p >
< div id =“edit_me”你可以编辑这个文本
当用户单击可编辑文本时,它将被一个填充文本的文本输入区域所取代,该文本可以被编辑。提交表单时,mymodule里/ myactionaction在Ajax中调用,并将编辑的值设置为价值参数。操作的结果更新可编辑元素。它写起来非常快,功能也非常强大。< / p >< p >的input_in_place_editor_tag ()Helper接受以下参数:< / p >< ul ><李>cols和rows:用于编辑的文本输入区域的大小(它变成一个textarea > <如果行大于1)。
textarea > <
行
loadTextURL
save_text
cancel_text
如果您厌倦了在模板中编写JavaScript来获得客户端行为,JavaScript助手提供了一个简单的替代方案。它们不仅自动化了基本的链接行为和元素更新,而且还提供了一种快速开发Ajax交互的方法。借助Prototype提供的强大语法增强和script.aculo提供的强大视觉效果。对我们来说,即使是复杂的交互也只需要几行字就能写出来。< / p >< p >由于制作一个高度交互性的应用程序就像使用symfony制作静态页面一样简单,您可以认为几乎所有桌面应用程序的交互性现在都可以在web应用程序中使用。ob娱乐下载< / p >< / div > 前一页< / >第十章-表格 下一个页面< / >第12章—高速缓存
本作品在GFDL许可下获得许可。< / p >< / div >< / div >< / div >< / div >< / div >< / div >