一步一个脚印。
重要的是,在进入下一步之前,一切都要按预期进行。
继续使用JSTL动态构建视图
只需继续使用JSTL,并仅使用
<ui:include>
直到你把一切都做好。不要改变太多。首先使其全部工作,然后重构为标记文件或复合文件。
在最初的JSP方法中,基本上是在JSTL的帮助下动态构建视图。您可以在JSF2.x中继续执行同样的操作,前提是您使用的是更新的JSFimpl版本,以防止视图范围的bean(Mojarra2.1.18+)损坏。你可以继续使用
<c:forEach>
,
<c:if>
和
<c:set>
在JSF中采用这种方式。您只需要更换
@include
和
<jsp:include>
通过
<ui:包含>
。请注意
<ui:包含>
具有与JSTL相同的生命周期。它也是一个标记处理程序,而不是一个组件。另请参见
JSTL in JSF2 Facelets... makes sense?
这个
<ui:fragment>
然而,它是一个UI组件。它不会有条件地构建视图。无论其结果如何
rendered
属性,它和它的所有子级仍将在JSF组件树中结束。它们只会在呈现响应阶段有条件地呈现HTML输出。与
<c: 如果>
JSF组件树的大小将在每个条件下增长。如果你有4个条件包含,它至少会增长4倍
inc_dynamic_checklist_v
文件只需继续使用JSTL动态构建视图。这是一个非常好的工具。另见a.o。
How to make a grid of JSF composite component?
另一种方法是通过
binding
,
findComponent()
,
createComponent()
,
new SomeComponent()
,
getChildren().add()
如果没有,这只会导致冗长而脆弱的代码,很难维护。绝对不要那样做。
这个
<f|o:viewParam>
正如你失败的尝试所显示的,它有不同的目的。他们无法行动
<ui:param>
中的值
<ui:包含>
正如你所料。它们仅对HTTP请求参数起作用。另请参见
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
你可以
<ui:包含>
继续使用
<ui:param>
而不是
<c: 设置>
,但您应该直接访问它们,就像您使用
<c: 设置>
唯一的区别是,这些变量仅在include本身内部可用,而不是在整个请求中可用(即,在include外部也可用)。JSP等价于
<ui:param>
顺便说一下
<jsp:param>
,你实际上应该首先使用它。
至于支持bean逻辑,只需将预处理Java代码放入
@PostConstruct
backing bean和backing bean的操作方法中的后处理Java代码
<h:commandXxx>
组件。这个
<f:viewAction>
和
preRenderView
因为它们在视图构建时间之后运行,因此JSTL无法得到预期的模型。仅用于处理用户提交的HTTP请求参数。
如果您被旧Mojarra版本中的鸡蛋视图状态错误咬了一口,您绝对无法升级,也无法通过设置禁用部分状态保存
javax.faces.PARTIAL_STATE_SAVING
到
false
,则不能将JSTL标记属性附加到视图范围内的bean属性。如果这里确实有一个视图范围的bean,并且这里不能选择使用请求范围的bean的话,那么您需要删除JSTL并以独占方式使用
<ui:repeat>
和
<ui:片段>
而不是
<c: 对于每个>
和
<c: 如果>
。但是,您可以继续使用
<c: 设置>
(如适用)。您还应该保持上述支持bean逻辑的指导原则。
将包含参数的重复include重构为标记文件
一旦你完成了所有的工作,那么你就可以开始查看带有参数的重复include(即。
<ui:include><ui:param>
多次使用的块),并通过在
your.taglib.xml
文件这实际上不会改变逻辑和流程,但会使代码更加干净和简洁。另请参见
How to create a custom Facelets tag?
完整的
*.taglib.xml
示例和注册
web.xml
.
该虚构示例包括“是/否/否检查表”
<ui:include src="/WEB-INF/includes/tristateChecklist.xhtml">
<ui:param name="value" value="#{actionItem}" />
</ui:include>
…可按如下方式使用
<my:tristateChecklist value="#{actionItem}" />
…在将物理文件移动到
/WEB-INF/tags/tristateChecklist.xhtml
并将其注册到
/WEB-INF/your.taglib.xml
如下所示,所有包含参数作为标记属性。
<tag>
<tag-name>tristateChecklist</tag-name>
<source>tags/tristateChecklist.xhtml</source>
<attribute>
<name>value</name>
<type>java.lang.Object</type><!-- TODO: fix type -->
</attribute>
</tag>
(你没有显示你的模型,所以我只是指定了一个过于通用的类型)
将重复模型前/后处理重构为复合材料
一旦您重新开始工作,就可以开始研究重复的模型预处理/后处理,并将它们重构为具有“支持组件”的复合结构,以及内部关联的XHTML
<cc:implementation>
.
基本上,当您在
@后期构造
将服务/DB返回的“外部”模型转换为视图所期望的“内部”模型,和/或当您有相当多的Java代码在操作方法将“内部”模式转换回服务/DB所期望的外部模型时,您可以考虑将其重构为可重用的复合组件。这样,当您想在不同的视图中重用相同的功能时,就不需要将此预处理/后处理任务复制粘贴/重复到不同的后台bean中。最后,您会看到一个视图,它引用的是“外部”模型类型而不是“内部”模型类型,可能由多个属性组成。
如果没有对所有模型预处理/后处理的完整概述,很难用具体案例的示例来回答这一部分。以下答案包含的示例应能充分了解复合组件的意义和无意义:
至少,我觉得你的“肉”可能是一个界面。如果有不同的对象/类具有相同的公共行为,那么应该创建一个定义该公共行为的接口,并让这些类实现该接口。这部分并不是严格意义上的JSF相关,而是“基本”Java。
别忘了:一步一个脚印。
使用标记文件和组合作为重构工具,以最小化代码重复。您应该已经有了完全可用的代码。