客户端JavaScript

多年来,Tapestry中没有什么比支持客户端JavaScript的方式更大的变化了。从一开始,我们的目标就是让JavaScript成为Tapestry世界的一流公民,并使其能够轻松地在组件中封装JavaScript。

相关文章

这个传统JavaScript第页讨论了早期的方法;Tapestry 5.4的主要功能是完全重写客户端的所有内容,目标如下:

  • 打破Tapestry与原型Scriptaculous公司,通过引入抽象层
  • 去掉笨拙的挂毯T5类“命名空间”
  • 减少页面特定JavaScript初始化的数量
  • 更容易覆盖与客户端元素关联的行为
  • 支持CoffeeScript和(可能)其他面向JavaScript的语言
  • 使用组织客户端JavaScript模块
  • 使页面加载更快
  • 整合引导数据库
  • 使富客户端库(如骨干安格拉尔JS在页面中操作
  • 正确记录Tapestry的客户端支持

总体愿景

Tapestry中客户端的总体设想是在几个不同的级别上进行封装。

在服务器端,Tapestry组件(或mixin)公开可配置参数。该组件编写DOM元素或属性,以及一些JavaScript初始化。这里的封装允许对客户端JavaScript知之甚少或一无所知的开发人员(作为精通客户端编码和Tapestry组件的开发人员创建的组件的消费者)享受这些好处。

在客户端,JavaScript与特殊标记相结合,生成所需的行为。。。从控制初始焦点字段到执行客户端输入字段验证,再到运行复杂的Ajax工作流。

在可能的情况下,所有这些行为都是由数据-元素上的属性,与顶级事件处理程序相结合。在客户端,事件不仅用于直接响应用户操作(使用“click”、“mouseOver”、“submit”或其他事件侦听器),还允许元素以各种方式协作。例如,输入验证基于触发每个表单控件元素上的特定自定义事件,然后顶级事件处理程序可以管理任意数量字段的验证。

原型与jQuery

几年来,Tapestry显然在Prototype和jQuery方面“支持错误的马”。当2007年或2008年制定第一个代码时,还不清楚jQuery以其奇怪的抽象和陌生的方法会继续征服世界。与此同时,Prototype与RubyonRails进行了非常紧密的集成,并拥有一流的文档和书籍。

尽管如此,jQuery也不是万能的。Tapestry 5.4引入了一个抽象层,允许许多组件编写代码,而不管基础框架是Prototype还是jQuery或其他什么。如果如果你喜欢jQuery,那么没有问题:只使用jQuery编写应用程序,就可以忽略抽象层中的许多特性。您的代码可能会更加高效。

如果您正在构建可重用组件或库,那么向抽象层写入可能是值得的;完全有可能有人会编写一个抽象层的替代品,以您最喜欢的基础框架为目标,例如ExtJS、MooTools或一些今天还不知道的东西。

重与轻

早期的Tapestry JavaScript是重的基本上,每个组件都会编写一些非常具体的JavaScript初始化,其中包括组件的DOM id和许多其他详细信息。此初始化将引用T5.单位命名空间。

那里的函数通常会通过其客户机DOM id定位特定元素,然后将事件处理程序附加到一个元素。它还可能创建某种形式的客户端控制器对象。这导致了一些问题:对于复杂页面(甚至可能是典型页面),页面底部JavaScript初始化的“blob”可能非常大。

使用单独的事件处理程序意味着Tapestry应用程序将使用更多的客户端对象,而定制的jQuery解决方案。。。因为jQuery中的常规方法是将单个事件处理程序附加到文档或正文,以处理冒泡到顶部的任何事件匹配CSS选择器。

在Tapestry 5.4中,目标是.在大多数情况下,没有特定的初始化功能;而是一个JavaScript模块加载,并安装一个或多个顶级事件处理程序;元素有数据-属性这些顶级处理程序用来识别他们负责的元素。

这是一种完整的生命周期方法;添加或删除页面内容(例如使用区域组件)使用顶级事件处理程序比每个元素事件处理程序更便宜,更不容易出错;在Internet Explorer下,内存泄漏的可能性也较小。

Internet Explorer因内存泄漏而闻名;它的DOM和JavaScript运行在不同类型的内存中,这些内存分别被垃圾收集。这意味着从JavaScript到DOM元素的引用将使DOM元素保持活动状态,即使这是任何地方对DOM元素唯一的引用。同时,事件处理程序JavaScript函数在DOM元素中保持活动状态,从而形成一个无法打破的循环。Prototype和jQuery等库在从DOM中删除事件处理程序时,必须从DOM元素中注销事件处理程序,以断开此链接。

这种方法的一个具体例子是客户端验证现在是如何工作的;过去,有一个复杂的类和事件监听器系统,它们特定于每个字段。现场控制器必须向表单控制器注册。验证者必须向现场控制器注册。

在5.4中,有许多数据-可以附加到任何DOM元素的属性。表单搜索具有非空值的元素数据验证; 每个这样的元素都有一系列触发的自定义事件。这些事件的顶级处理程序会在整个文档中接收元素的通知。

t5/core/validation.coffee(部分)
定义[“下划线”,“./dom”,“../events”,“.0/utils”,“.messages”,“.e/fields”],(_、dom、事件、utils、消息)->... dom.onDocument events.field.optional,“[数据选项=必需]”,(事件,备忘录)->如果utils.isBlank memo.valuememo.error=(@attr“data-required-message”)或“required”... dom.onDocument events.field.validate,“[data-validate-min-length]”,(事件,备忘录)->min=parseInt@attr“data-validate-min-length”如果memo.translated.length<最小值memo.error=(@attr“data-min-length-message”)或“太短”返回false

The t5/核心/事件模块为不同的自定义事件名称定义常量,这也是一个方便的地方挂起文档关于那些事件。

The t5/核心/dom名称空间是抽象层。 在文档上是附加顶级事件处理程序的简便方法。

必填字段具有属性数据可选性=必需; 事件处理程序被传递给备忘录包含价值属性中的值。如果值为空,则更容易生成错误。由于准确的错误消息可能是自定义或本地化的,因此它也在元素中提供数据请求消息属性。设置备忘录错误验证错误字符串导致用错误消息修饰字段,并指示表单本身有错误,尚未准备好提交。

可选性检查后触发不同的事件;The 备忘录.翻译属性是验证前转换的值(例如,对于数字字段,它将从字符串转换为数字)。再一次错误属性,并且返回false确保事件不再冒泡到包含元素或事件处理程序。

在这种总体方法中非常有用的是,字段是由Tapestry在服务器上呈现还是在客户端本地呈现(可能使用Backbone或AngularJS)不再重要。只要他们有正确的数据-属性,然后它们可以参与Tapestry的整个表单验证和提交周期,甚至可以利用默认的验证装饰行为。

抽象层

抽象层由t5/core/dom模块。该模块目前有两种不同的实现——一种是围绕Prototype的包装器,另一种是关于jQuery的包装器。

由此产生的抽象层有点混合;它大部分看起来像jQuery,但事件看起来更像Prototype。它也没有jQuery的操作匹配元素集的概念。

抽象既是过渡性的,也是永久性的。这是一种过渡,因为它是关于允许对Prototype进行大量投资的现有站点继续与Prototypy一起运行。它是永久性的,因为第三方库开发人员希望在Tapestry的客户端代码和任何底层框架之间保留一个抽象层,以便特定的应用程序可以提供自己的抽象层并在不破坏内置组件的情况下运行。

大多数应用程序应该过渡到jQuery,并可以直接使用jQuery。最好还是注入模块查询到您自己的模块中(通常作为参数$). 

如果您正在编写第三方应用程序并希望最大限度地重用,那么请使用抽象层。

通常更容易使用抽象层来正确响应定制Tapestry事件。