[请注意,由于Javaeye博客有很多bug,插入文章的代码段的显示有很多的错误,注意自己正确辨别]
Tapestry给我得第一感觉是想法非常不错,把界面的渲染和界面的数据、逻辑分离的很彻底,但是对于程序员来说写程序并不是很直观。而且有关文档、资料和书籍都不多。特别是一些复杂点的需求不知从何下手。经过一段时间的学习,我也总结了一些,以下所有内容都是基于Tapestry 4.1.3版本的。
基础
实现一个页面需要有三个文件:*.html, *.page, *.java(好象有点麻烦哦,不过在某些简单、极端的情况下page文件和java文件可以省略掉),html模板和page文件名字需要相同,Java类的名字不强制,他是在page文件里显式关联的。这样有个好处,多个page可以共用一个java类,不过这样做法可能有点乱。
模板(html)的搜索路径
Tapestry会首先page定义的路径下搜索html模板,然后在Web应用Context的根路径下搜索--也就是说在WebRoot/下搜索。这样我们可以选择把html模板和page放在一起或者放在WebRoot下。
把html模板放在WebRoot下有个好处,可以不需要page文件(如果有必要的话),反过来说,如果你没有定义page文件,那就只能放在WebRoot下了。
为了便于分类,我们可以把html模板和page文件放到子目录下面,如 WebRoot/Pages/User/UserReg.*。 但是这样需要在相应的地方把完整的路径都写上。可能会有以下几处:
1. Java类的listener方法处理后跳转的页面:如
java 代码
-
@InjectPage
(
"Pages/User/UserList"
)
-
public
abstract
IPage getUserListPage();
2. 链接:
-
/app?
service
=
page
&
page
=
Pages
/User/UserReg
-
/Pages/User/UserReg, $Direct?
sp
=
XXX
组件搜索路径
有以下几个:
-
根据在*.application中用
显式定义的组件类型的路径
-
*.application所在的目录,通常是WEB-INF
- WEB-INF/ servlet-name
目录,
servlet-name
也就是在web.xml中配置的名字。
-
Web项目根目录,也就是/WebRoot
一般情况可以使用第三种,这样比较不乱,可以将所有组件放在一起,通常自定义组件都不会太多。
链接
链接在Tapestry里似乎不是问题,因为它变的非常的对象化;但是用起来又好像有很多的问题。比较常用的链接组件是DirectLink和PageLink,下面是他们的用法:
DirectLink
用法一:可以这样用:
HTML
-
<
a
jwcid
=
"@DirectLink"
listener
=
"listener:prepareUserEdit"
parameters
=
"ognl:user.id"
href
=
"#"
>
Edit
<!-- -->a
>
listener是处理链接点击的方法名,parameters是参数,对应的的方法是
java 代码
-
public
IPage prepareUserEdit(String id){
-
-
}
注意这里的参数,如果这个参数如果不是String的而是int话,这个listener方法要这么:
java 代码
-
public
IPage prepareUserEdit(
int
id){
-
-
}
Tapestry会自动判断数据类型。
用法二:
将用法一中的HTML模板内的绑定信息搬到page文件中:
HTML
-
<
a
jwcid
=
"menuItem"
href
=
"#"
>
xxx
<!-- -->a
>
page
-
<
component
id
=
"menuItem"
type
=
"DirectLink"
>
-
<
binding
name
=
"listener"
value
=
"listener:doClickMenuItem"
/>
-
<
binding
name
=
"parameters"
value
=
"ongl:xxx"
/>
-
<
binding
name
=
"target"
value
=
"literal:Content"
/>
-
<!-- -->component
>
怎么样,HTML模板现在看上很简洁吧。
个人觉得第二种方式好一些,虽然要多写一些,但是它使得HTML代码很“干净”,特别是页面比较复杂的时候,即便不复杂,HTML里面也不应该有太多与显示无关的东西。当然,如果是特别简单的情况,那就无所谓了。
技巧:
如果要给链接传多个参数,两种方法的parameters这么写:
HTML
-
parameters
="
ognl
:{userName, id}"
Page
-
<
binding
name
=
"parameters"
value
=
"ognl:{userName, id}"
/>
PageLink
方法一:
HTML
-
<
a
jwcid
=
"@PageLink"
page
=
"Page1"
>
go to Page1
<
a
>
点击这个链接会直接跳转到名为Page1的页面。
方法二:
HTML
-
<
a
jwcid
=
"page2"
>
go to Page2
<
a
>
page
-
<
component
id
=
"page2"
type
=
"PageLink"
>
-
<
binding
name
=
"page"
value
=
"literal:Page2"
/>
-
<
component
>
PageLink一般比较简单,只是页面的跳转,两个方法都可以。
硬编码超链接:
如果我们不使用链接组件,要自己动态生成一个对某个页面的超链接该怎么办呢?这个URL该如何写呢?参数如何传递呢?
在文档里我只找到了诸如 "/app?service=page&page=xxx"的URL写法,但是这样的链接只能页面间跳转,无法绑定listener方法并传递参数,似乎作者不希望人们这么做。但是我观察带参数的DirectLink生成的网页链接,如:
-
/Users,$DirectLink.direct?
sp
=
l1
看起来Users就是当前页面,$DirectLink是链接组件的名字,如果没有显式的指定的话就自动采用组件的名字加上$前缀,如果有其他无名链接就会出现类似$DirectLink_0, $DirectLink_1的链接, sp=l1看起来就是参数了。这样我们不用链接组件也可以自己生成网页超链接了。
当然,我们还是要在page文件里写上对应的组件声明进行绑定--我们还没告诉它要如何处理这个链接的点击操作呢。如下面的例子:
HTML
-
/TreeMenuPage,menuItem.direct?
sp
=
item_01
&
sp
=
doSomthing
xml 代码
-
<
component
id
=
"menuItem"
type
=
"DirectLink"
>
-
<
binding
name
=
"listener"
value
=
"listener:doClickMenuItem"
/>
-
<
binding
name
=
"target"
value
=
"literal:Menu"
/>
-
<
component
>
java 代码
-
public
IPage doClickMenuItem(String itemId, String itemName) {
-
-
}
链接的名字不是什么$DirectLink了,必须和page里声明的组件的名字一致。注意链接参数的顺序和Java类listener方法的参数顺序应该也是一致的。
Form相关组件
Form相关组件的使用应该算是比较简单的。但是有几个点要说一下:
Hidden组件
Hidden组件和TextField组件有些不一样,废话,一个显示一个不显示,不过我要说的不是这个。Hidden和TextFiled组件在渲染页面的的时候经常要给一个初始化值(如果有的话),不同的是Hidden组件会在值的前面加一个前缀,如果是String类型就加S,如果是long型的就加l,以此类推。不过好像Tapestry在提交Hidden的时候会自动处理这个前缀,所以无需担心类型转换错误。
与For组件一起使用
如果将Form的组件于For组件一起使用的话,For组件会将数据转换成字符串并存储在Hidden组件内。也就是说,如果For组件使用的数据无法被序列化的话,Tapestry就会报错,抛出ApplicationRuntimeException异常。例如,如果你要循环输出若干了User对象给Select组件,形成的话一个User列表框的话,你的User对象必须序列化:
java 代码
-
public
class
User
implements
Serializable
多个Submit按钮
当需要多个Sumit按钮来提交同一个Form,用不同的listener方法来处理的时候,可以在默认的submit组件后添加另外一个submit组件,指定listner 方法,如:
xml 代码
-
<
input
type
=
"submit"
jwcid
=
"help@Submit"
action
=
"listener:doHelp"
value
=
"Help"
/>
自定义组件
自定义组件也和定义Page一样需要三个文件,一个组件的模板,也是一个html文件,一个*.jwc文件和一个Java类。其实自定义组件的方法和定义Page几乎完全一样,除了实现的接口不一样之外。要注意的是一下几点:
body
如果需要自定义组件包含其他组件或者html元素的话,需要在组件模板内使用@RenderBody组件,如:
-
<
span
jwcid
=
"@RenderBody"
>
Unique content goes here.
<!-- -->span
>
那么用自定义组件包含的内容都会被渲染,如:
-
<
span
jwcid
=
"@UserComponent"
>
<
a
href
=
"#"
>
Hello World
<!-- -->a
>
<!-- -->span
>
如果组件内有数据提交,要处理提交的数据的话,要在renderComponent()里做
java 代码
-
if
(cycle.isRewinding()){
-
......
-
}
JavaScript
可以把JavaScript代码从html模板中分离出来实现代码重用,在Tapestry下可以用传统的方式引入js文件,但是如果你需要在Tapestry处理JavaScript里的某些数据的话,就需要使用Tapestry的方式,把JavaScript代码放到后缀为×.script的XML文件中,如:
xml 代码
-
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
-
-
"-//Apache Software Foundation//Tapestry Script Specification 3.0//EN"
-
"http://jakarta.apache.org/tapestry/dtd/Script_3_0.dtd">
-
<
script
>
-
<
input-symbol
key
=
"symbol"
required
=
"yes"
/>
-
<
body
>
-
<!-- -->
-
<!-- -->body
>
-
<!-- -->script
>
注意JavaScript代码段的body部分要加
xml 代码
标签,很显然,JavaScript不符合XML格式。
使用的时候在html模板内直接引用:
-
<
span
jwcid
=
"myScript"
/>
给script传递参数:
上面代码段中的<
input-symbol
key
=
"symbol"
required
=
"yes"
/>就是script的参数
StyleSheet
StyleSheet不是在html模板中直接定义的,也是通过Tapestry作为asset来实现的。当然你完全可以在html模板中指定css文件路径,不过那通常是给模板的编辑人员使用的。那么在Tapestry中应该怎么样使用呢?
假如你的css文件在WebRoot/css下面。那么在你的xxx.page里加上
-
<
asset
name
=
"stylesheet"
path
=
"css/style.css"
/>
在你的xxx.html模板中用Shell组件包裹你的body标签,把你在page里声明的stylesheet赋给Shell组件
xml 代码
-
<
span
jwcid
=
"@Shell"
stylesheet
=
"asset:stylesheet"
>
-
<
body
jwcid
=
"@Body"
>
-
-
......
-
-
</
body
>
-
</
span
>
这样的话整个页面就应用了这个css/style.css了。
分享到:
相关推荐
本文档旨在提供一个全面且易于理解的 Tapestry 学习指南,帮助初学者快速上手并掌握 Tapestry 5.1 的核心功能。 #### 第一章:搭建 Tapestry 5.1 开发环境 ##### 1.1 安装 JDK - **原因**:Tapestry 5.1 使用了 ...
【Tapestry笔记】 Tapestry是一个基于Java的Web应用框架,它采用了面向组件的开发方式,这使得它与其他如Structs...通过学习Tapestry,开发者可以掌握一种新的、更为先进的Web应用开发模式,提升开发效率和代码质量。
通过本教程的学习,你已经了解了Tapestry 5的基础知识及其在实际开发中的应用。Tapestry 5不仅简化了Web应用程序的开发过程,还为开发者提供了丰富的工具和特性来构建高质量的Web应用。希望本教程能够为你开启...
本书主要面向希望学习或提高 Tapestry 5 技能的 Java 开发者。无论您是初学者还是有一定经验的开发者,都可以从中获得有价值的见解和实用的技巧。 #### 三、核心内容概览 ##### 1. **基础概念** - **Tapestry 5 ...
总结来说,Apache Tapestry 5 是一个强大且全面的Web开发框架,它的面向组件特性和内建的Ajax支持,以及强大的状态管理和依赖注入功能,使得开发高效、安全、可维护的Web应用变得更加容易。通过学习和掌握Tapestry 5...
| 学习曲线较陡峭;灵活性较低。 | **Tapestry的特点:** - **高效的组件模型:**Tapestry通过组件模型简化了Web开发过程。 - **强大的社区支持:**虽然文档和支持资源相比其他框架可能较少,但Tapestry仍然拥有...
总结来说,Tapestry的Table和Tree组件提供了强大而灵活的数据展示工具,它们不仅简化了数据的布局和交互,还允许开发者专注于业务逻辑,提高开发效率。通过深入学习这两个组件,你将在构建复杂Web应用时更加得心应手...
通过“tapestry学习”的压缩包文件,我们可以期待找到一系列有关Tapestry的学习资料,包括入门指南、示例代码、API文档等,这些都将有助于我们全面掌握Tapestry的使用技巧和最佳实践。 总结来说,Tapestry是一个...
### Apache Tapestry5 使用教程详解 ...无论是对于初学者还是有经验的开发者来说,Tapestry 都是一个值得学习和使用的框架。通过掌握其核心概念和功能,开发者可以快速构建出既美观又实用的 Web 应用程序。
总结,"Tapestry开发指南0.9"涵盖了从基础到高级的Tapestry开发知识,对于想要深入理解这个框架的开发者来说是一份宝贵的资源。虽然版本较旧,但其核心理念和设计模式在后续版本中依然得到保留,因此学习它有助于...
根据提供的信息,我们可以总结出以下关于“Tapestry in Action”的相关知识点: ### 书籍基本信息 - **书名**:Tapestry in Action - **作者**:Howard M. Lewis Ship - **出版社**:Manning Publications Co. - *...
**特点总结**: - **MVC 结合模板技术**:Tapestry 将 MVC 框架和视图层的模板技术结合起来,允许开发者完全避免使用 JSP 技术,转而使用 Tapestry 提供的模板技术。 - **视图逻辑与业务逻辑分离**:通过这种设计,...
总结来说,Apache Tapestry 5.3.7 是一个强大而现代的Web开发框架,它的组件化设计、类型安全、强大的开发工具支持以及优秀的性能,使得它成为构建复杂企业级Web应用的理想选择。通过研究提供的源码、API文档和二...
总结来说,Tapestry5是一个全面的Web开发解决方案,以其组件化、高效和易用性赢得了开发者们的青睐。通过深入学习和实践,开发者可以利用Tapestry5构建出更优雅、更易用、更安全且更具弹性的Web应用程序。
总结来说,Tapestry是一个功能强大且具有创新性的Web框架,它提供了一种不同于Struts的开发模式,更注重代码的简洁性和开发者的体验。尽管学习曲线相对较陡,但其优势在于提高开发效率、简化错误处理和增强代码的可...
《Tapestry in Action》不仅是一本学习Tapestry框架的入门书籍,更是深入理解其核心概念、掌握高级技术和最佳实践的宝贵资源。无论是初学者还是有一定经验的开发者,都能从中获得有价值的信息,提升使用Tapestry构建...
有助于学习tapestry框架,尤其是内部封装的相关东西的总结!仅作参考
#### 三、如何通过本书学习Tapestry 本书采取了教程式的学习方法,通过一系列逐步指导的例子帮助读者快速上手Tapestry框架。它具有以下特点: 1. **步骤清晰**:本书按照逐步的方式引导读者完成实际案例,确保每个...
总结来说,Tapestry是一个强大的Java Web开发框架,其组件化设计和事件驱动的模式简化了复杂Web应用的构建。这份用户手册将引导读者深入理解和应用Tapestry,无论你是初学者还是经验丰富的开发者,都能从中受益匪浅...