5.复杂的Tiles<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

到目前为止,我们已经介绍了简单的Tiles描述。我们知道了如何使用最通常的例子。现在是学习更多Tiles的时候了:Tiles到底是什么?如何用Tiles处理复杂的商业逻辑?还有什么不同的标签能传递属性给Tiles?
5.1 什么是Tiles?

一个Tiles是网页的一个区域。这个区域是矩形的,也可以叫做Region(就像David Geary的其他模板机制)。
汇集很多Tiles能够组成一个新的Tiles。一个网页的Tiles能够递归的构建,并且表示成一棵每个节点表示区域的树。根节点通常就是这个页面,最终节点或者是叶子节点包含内容,中间节点通常包含布局。
5.1.1 属性

一个Tile是可以参数化的,这意味着它可以接受某些参数,Tiles为了避免和request参数区别,称其为属性(attribute)Tiles属性在插入时定义,并且只能对这个tiles可见。它不能被子tiles和外边的tiles见到,这就避免了在同一页面中重复使用同一tiles时的名字冲突。还允许tiles的设计者在不同的tiles使用相同的属性名,使他们关注于Tiles的实际,不在名字冲突上浪费时间。
5.2 为视图准备数据 :加入控制器(controller

我们总是需要为jsp页面准备数据。在MVC框架中,控制器来准备数据(在model中)。翻译成TilesStruts的话来说,我们能使用Struts Action作为控制器,JSP页面作为视图,用Tiles结合二者。当你插入Tiles是,ActionJSP页面实际显示之前被调用。现在,你的复杂的网页就能够由控制器控制的tiles来组成(一个子控制器对应一个Tiles)。这样比一个控制器控制所有的tiles要好,因为这样做能真正允许构建自动化tiles,不用关心如何控制他们。
有很多方法可以用来使用tiles关联ActionView:
l         <insert>或者<definition>中指定Action类或者Action URLTiles 1.1
l         struts-config.xml中使用Struts Action,让它来转发到一个定义名。在tiles-config.xmlAction URL指定一个目标名作为页面,用视图指定另一个定义作为实际页面,第一个定义用来当作完整的Tiles定义(ation + view),第二个定义用做视图定义。[origin: In tiles-config.xml  specify one definition with the action URL as page, and the definition with the view as the page. The first definition is used as the complete Tiles definition(action+view), the second definition is used as the view definition]
l         一个控制器关联多个视图是可能的。从中选择一个适当的,这在你有一个主视图和一个错误视图的情况下特别有用。除了不只一个转发和视图定义,其他的和前边一样。

5.2.1一个控制器——一个视图

<insert><definition>标签中关联“控制器”到一个Tile是可能的。关联的最简单的方式是在<insert><definition>中指定。你能够把一个本地的URL或者是一个类作为一个控制器关联。这个控制器在JSP页面被显示前被立即调用,它共享一个jsp页面中相同的tiles上下文。所以,它可能读取,修改,或者是添加tiles属性。
这个控制器能有很多用途:
l         在传递给视图之前交互数据模型
l         在传递给视图之前改变或者添加某些属性
如果你使用URL作为控制器,那它应该是当前应用程序的URL。你能使用Struts Action URL。如果是这种情况,你要继承org.apache.struts.action.TilesAction,而不是继承原来的StrutsAction类。这个TilesAction除了实现原来的perform方法,还提供了一个拥有额外参数:tileContext的新perform()。当你需要与Tiles属×××互是,它是有用的。
如果你使用类名作为控制器,它需要继承下列基类或者接口的一个:
l         org.apache.struts.tiles.Controller
这个接口定义了控制器方法。这个方法接受当前Tiles的上下文作为参数,还包括了通常的servlet的参数:requestresponseservletContext
l         org.apache.struts.tiles.ControllerSupport
这是一个只用空方法的基本实现。
l         org.apache.struts.action.Action(外覆org.apache.struts.action.strutsActionWrapper)
如果你提供Struts Action子类,它要外覆适当的类,strutsperform将被调用,不过mappingfrom将是null
       Class 作为控制器插入的例子:
<tiles:insert page=”layout.jsp”

              controllerClass=”org.apache.struts.examples.tiles.test.TestTilesController”>

       <tiles:put name=”title” value=”Test controller set in insert” />

       <tiles:put name=”header” value="/”head.jsp”" />

       <tiles:put name=”body” value="/”body.jsp”" />

</tiles:insert>

5.2.2 一个控制器——多个视图

有时,控制器做一些逻辑操作然后依据结果选择适当的视图来提供数据。比如,控制器处理用户输入,如果正确,数据将提供,否则,适当的错误页面出现。
当前版本的tiles不直接支持一个控制器关联多个视图,不过可以利用StrutsAction Forward机制来实现。
这个解决方案包括写一个包含它的属性的Tile(insertdefinition),并且指定一个Struts Action作为页面的url而不是jsp页。Action扮演了控制器的角色,转发到适当的JSP页面,这些页面要么是URL要么是definition名。控制器和选择页面的Tile上下文将一致,允许你修改或设置Tiles属性。
Tile定义如下:
<definition name=”tileWithActionCotroller” path=”/actionAsController.do”>

<put name=”title” value=”Title” />

<put name=”anAttribute” value=”aValue” />

</definition>

Action作为控制器和转发器
<action path=”/actionAsController” type=”org.apahce.struts.examples.tiles.ActionAsController”>
       <forward name=”failture” path=”/faiturePage.jsp” />
       <forward name=”success” path=”success.definition” />
</action>
在这个例子中,failture关联一个jsp页面,而success关联一个定义名。如果success被选择,definition将被载入,已经在definition定义过了但实际还没有加到Tiles上下文的属性将被加入到当前上下文,这样允许给视图提供默认属性值。