用 JavaServer Faces 2 实现可扩展 UI (4)
 
- UID
- 1066743
|

用 JavaServer Faces 2 实现可扩展 UI (4)
实现了一个表单,并且此表单使用了一个图标组件。(我随后会在 一节对该图标组件进行详细讨论。目前,只需知道页面作者可以用一个图标关联图像和方法。)这个 logout 图标的图像显示在 的底部,而此 logout 图标的方法 — places.logout()— 则如清单 7 所示:清单 7. Places.logout() 方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| package com.clarity;
...
@ManagedBean()
@SessionScoped
public class Places {
private ArrayList< lace> places = null;
...
private static SelectItem[] zoomLevelItems = {
...
public String logout() {
FacesContext fc = FacesContext.getCurrentInstance();
ELResolver elResolver = fc.getApplication().getELResolver();
User user = (User)elResolver.getValue(
fc.getELContext(), null, "user");
user.setName("");
user.setPassword("");
setPlacesList(null);
return "login";
}
}
|
对我而言,— places 视图的左菜单的实现 — 已经十分接近 30 行的代码长度限制。此清单有点难于读懂,并且该代码片段内的表单和图标可被重构成各自的文件。清单 8 显示了 的重构版,其中,表单和图标被封装进各自的 XHTML 文件:
清单 8. 重构 places 视图的左菜单1
2
3
4
5
6
7
8
9
10
11
12
13
| <ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<div class="placesSearchForm">
<div class="placesSearchFormHeading">
#{msgs.findAPlace}
</div>
<ui:include src="addressForm.xhtml">
<ui:include src="logoutIcon.xhtml">
</div>
</ui:composition>
|
清单 9 显示了 addressForm.xhtml:
清单 9. addressForm.xhtml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| <ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:form prependId="false">
<h:panelGrid columns="2">
#{msgs.streetAddress}
<h:inputText value="#{place.streetAddress}" size="15"/>
#{msgs.city} <h:inputText value="#{place.city}" size="10"/>
#{msgs.state} <h:inputText value="#{place.state}" size="3"/>
#{msgs.zip} <h:inputText value="#{place.zip}" size="5"/>
<h:commandButton value="#{msgs.goButtonText}"
style="font-family alatino;font-style:italic"
action="#{place.fetch}"/>
</h:panelGrid>
</h:form>
</ui:composition>
|
清单 10 显示了 logoutIcon.xhtml:
清单 10. logoutIcon.xhtml1
2
3
4
5
6
7
8
9
| <ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:util="http://java.sun.com/jsf/composite/components/util">
<util:icon image="#{resource['images:back.jpg']}"
actionMethod="#{places.logout}"
style="border: thin solid lightBlue"/>
</ui:composition>
|
在从多个小文件组装视图时,就可享受到 Smalltalk 的 Composed Method 模式的益处。您还可以组织这些文件以便更易于对更改做出反应。例如,图 4 显示了构成 places 应用程序内的这三个视图的文件:
图 4. places 应用程序的视图 我所创建的这三个目录 — views、sections 和 templates — 包含了用来实现 places 应用程序视图的大多数 XHTML 文件。由于 views 和 templates 目录内的文件很少更改,因此我更多关注的是 sections 目录。例如,若我想要更改 login 页面左菜单内的图标,我就知道该到哪里去更改:sections/login/menuLeft.xhtml。
当然,您可以使用任何目录结构来组织您的 XHTML 文件。如果组织得合理,定位想要修改的代码就会非常容易。
除了遵循 DRY 原则和使用 Composed Method 模式之外,还有一种好的做法是在定制组件内封装功能。组件是一种功能强大的重用机制,而且您应该充分利用这种强大性。与 JSF 1 不同,使用 JSF 2 更易于实现定制组件。 |
|
|
|
|
|